在第二个可观察对象中修改第一个可观察对象的结果并 return 更新结果

Modify result of first observable in second observable and return updated result

我有一个方法 exampleMethod() returns 2 个连续服务调用(getData1()getData2())的结果,而 getData2() 必须修改getData1()exampleMethod() returns 之前返回的数据。目前,嵌套服务调用在我们已经从 exampleMethod() 返回之后执行,但为时已晚。我知道在另一个可观察对象中调用订阅是一种不好的做法,可能会导致问题,所以我想问的是什么是正确的方法。下面的示例代码。谢谢!

exampleMethod() {
    return this.myService.getData1()
      .pipe(
        map(res => {
          res.orders = someValue;
          return res;
        }),
        map(res => {
          res.orders.forEach((order: any) => {
            this.myService.getData2()
              .pipe(
                tap((orders: any[]) =>
                  order.status = orders.find(o=> o.number === order.number).status // <<====== this resolves after we've already returned from exampleMethod()
                )
              ).subscribe();
          });
          return res; // <<====== status value of res.orders not set
        })
      );
  }

你说内部订阅不优雅是对的。您需要 RxJS switchMap 运算符和 forkJoin 函数来处理多个同时请求。

尝试以下方法

exampleMethod(): Observable<any> {   // <-- define return type here
  return this.myService.getData1().pipe(
    map(res => ({...res, res.orders: someValue})),
    switchMap(res =>
      forkJoin(
        res.orders.map(order =>
          this.myService.getData2().pipe(map((orders: any[]) =>       // <-- pip the `map` operator here
            ({...res, res.status: orders.find(o => o.number === order.number).status})
          ))
        )
      )
    )
  );
}

编辑:为 RxJS map

包含 pipe

您可以使用高阶 Observable 来做到这一点。我怀疑 switchMap 可能不是您要查找的内容,而是 concatMap or concatAll.

return this.myService.getData1().pipe(
    map((res) => {
      res.orders = ["someValue"];
      return res;
    }),
    map((res) => 
      // <-- use switch map to internally subscribe to inner observable
      res.orders.forEach((order: any) => 
        this.myService.getData2().pipe(
          first(),
          tap(/* do something */)
        );
      )
    ),
    concatAll(), // <-- concat all inner-observables values in order
    last() // ensure that only the last value is emitted to outer observable
  );

不过要记住一件事,可观察对象不会同步发出值。因此,在 observable 处理任何值之前,exampleMethod() 将始终 return。一种方法,尽管我不推荐它,是在异步方法中等待可观察对象的完成:

async function exampleMethod(){
    return await this.dataService.getData()
       .pipe(/* whatever*/ )
       .toPromise(); // this will resolve when the observable is complete
}