RXJS在管道中合并多个可观察对象

时间:2019-06-17 14:47:06

标签: angular rxjs rxjs-pipeable-operators

我有一个API调用,它返回一定数量的ID。 这些ID均用于进行新的api调用。这些API调用的结果需要合并为一个对象。

首先,我在第一个api调用的.pipe(map)运算符内使用了一个循环。在此循环中,我进行了第二次api调用,并在每个调用中的.pipe(map)运算符中,都在角度组件中编辑了一个变量。

这不是很漂亮,我实际上在想这是否线程安全。我知道javascript是单线程的,但是让多个异步进程与同一个全局变量混淆似乎并不十分安全。

之后,我通过将apiCall1循环返回的Ids,将第二个api调用返回的可观察值存储在数组中,并使用forkJoin相应地订阅和处理每个结果(请参见示例)。

但是,这不是很漂亮,我想知道是否可以在管道中使用一个运算符来实现此目的?

所以不是(伪代码):

  .pipe(
      map(ids=> {

        let observables = []
        for (const id of ids) {
         observables.push(this.service.getSomeStuff(id));
        }

        forkJoin(...observables).subscribe(dataArray) => {
          for (data of dataArray) {
            //Do something
          }
        });

      }),
      takeWhile(() => this.componentActive),
      catchError(error => {
        console.log(error);
        return throwError(error);
      })
    )
    .subscribe();

有没有这样的运算符:

  .pipe(
      map(ids=> {

        let observables = []
        for (const id of ids) {
         observables.push(this.service.getSomeStuff(id));
        }

      return observables
      }),
      forkJoin(dataArray => {
          for (data of dataArray) {
            //Do something
          }
        });
      takeWhile(() => this.componentActive),
      catchError(error => {
        console.log(error);
        return throwError(error);
      })
    )
    .subscribe();

3 个答案:

答案 0 :(得分:2)

这是您可以做的:

sourceObservable$.pipe(
  // depends on your need here you can use mergeMap as well
  switchMap(ids => {
    const observables = ids.map(i => this.service.getSomeStuff(id));
    return forkJoin(observables);
  }),
  tap(joined => {
    // joined will be an array of values of the observables in the same
    // order as you pushed in forkJoin
    for (data of joined) {
      // do something
    }
  }),
  takeWhile(() => this.componentActive),
  catchError(error => {
    console.log(error);
    return throwError(error);
  })
)
.subscribe();

答案 1 :(得分:0)

为什么不立即使用for来修改您的数据,为什么在接收到数据后却不这样做呢?像这样的东西。

source$.pipe(
  mergeMap(ids => from(ids)),
  mergeMap(id => this.service.getSomeStuff(id)),
  tap(data => //do someting with the data);
  takeWhile(() => this.componentActive),
  catchError(error => {
    console.log(error);
    return throwError(error);
  }),
  toArray(), --> this create the array of all the values received.
)
.subscribe(data => //returns array of modified data);

答案 2 :(得分:0)

combineLatest(...observables)

仅在所有可观察物都发出之后才发出,并且您将获得一系列结果。