簡體   English   中英

RXJS 在管道內組合多個可觀察對象

[英]RXJS Combining multiple observables inside a pipe

我有一個返回一定數量 id 的 API 調用。 這些 id 中的每一個都用於進行新的 api 調用。 這些 API 調用的結果需要組合成一個對象。

起初,我在第一個 api 調用的 .pipe(map) 運算符中使用了一個循環。 在這個循環中,我進行了第二個 api 調用,並且在每個調用的 .pipe(map) 運算符中,我將在我的 angular 組件中編輯一個變量。

這不是很漂亮,我實際上想知道這是否是線程安全的。 我知道 javascript 是單線程的,但是讓多個異步進程混淆同一個全局變量似乎不太安全。

之后,我只是通過循環 apiCall1 返回的 Id 將第二個 api 調用返回的 observable 存儲在數組中,並使用 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();

這是你可以做的:

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();
combineLatest(...observables)

只會在所有 observable 發出后才會發出,並且您將擁有一個結果數組。

與其使用 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM