簡體   English   中英

如何合並多個可觀察到的RxJS的結果?

[英]How to combine the results of multiple observable, RxJS?

我正在學習RxJS,並嘗試用之前的Promise替換一些我做過的代碼,但我一直在努力尋找正確的方法來組合可觀察對象。

我有一個調用多個API的代碼,並且每個API調用都執行相同的代碼。 而且,在完成API調用之后,我還有一些其他代碼只能執行一次,並且只能執行一次。 我用Promises做到了這一點,我做了多個Promises,對於每個Promise我都執行相同的代碼,在Promise.all()我只做其他代碼。

所以我試圖用RxJS做到這一點:

var apiCallIterator = ["id1", "id2", id3];
var apiCallObservable = from(apiCallIterator)
  .pipe(
    mergeMap(apiCallIterator => {
      return makeAnApiCall();
    })
   );

apiCallObservable.subscribe({
next: value => {
 // do some code for each API call
},
error: () => {
 // api call failed
}
})

這對於我的任務的第一部分效果很好,它將在每次API調用完成后執行相同的代碼。 但是在所有API調用完成之后,我找不到一種將所有結果都集中到一個位置的方法。

也許我從一開始就做錯了,但是這部分似乎對我來說很好。

最簡單的方法是添加toArray()

from(apiCallIterator)
  .pipe(
    mergeMap(val => makeAnApiCall()),
    toArray(), // collect all results
  )
  .subscribe(allResults => ...); // allResults.forEach(...) to iterate all results

您也可以使用forkJoin但是您必須事先准備所有Observables源的數組。 但是,這僅是您的偏愛。

https://stackblitz.com/edit/rxjs6-demo-qbvhjh?file=index.ts

使用forkJoin可以實現

forkJoin是一個運算符,它采用任意數量的Observable,可以將其作為數組或直接作為參數傳遞。 如果沒有提供輸入Observables,則結果流將立即完成。

forkJoin將等待所有傳遞的Observable完成,然后它將發出一個數組,其中包含來自相應Observable的最后一個值。 因此,如果將n個Observable傳遞給運算符,則結果數組將具有n個值,其中第一個值是第一個Observable發出的最后一個值,第二個值是第二個Observable發出的最后一個值,依此類推。

我認為您需要forkJoin運算符。

當您有一組可觀測對象且僅在乎每個對象的最終發射值時,最好使用此運算符。 一個常見的用例是,如果您希望在頁面加載(或其他事件)時發出多個請求,並且只希望在收到所有響應后才采取措施。 這樣,它類似於您可能使用Promise.all的方式。 https://www.learnrxjs.io/operators/combination/forkjoin.html

對於您的代碼:

var apiCallIterator = ["id1", "id2", id3];
var apiCallObservable = from(apiCallIterator)
  .pipe(
    mergeMap(apiCallIterator => {
      return makeAnApiCall();
    })
   );

forkJoin(apiCallObservable)
  .subscribe( 
     (combinedCalls) => {
        console.log(combinedCalls) //receive all the values at once
     },
     (error) => {
     // api call failed
     }
   })

您可以對它們全部進行zip() ,這只會在所有可觀察對象完成后才發出。

var apiCallIterator = ['id1', 'id2', 'id3'];

var apiCallObservable = zip(apiCallIterator.map(id => makeAnApiCall(id)))
  .subscribe({
    next: value => {
      // do some code for each API call
    },    
    error: () => {    
      // api call failed    
    }    
  })

makeAnApiCall(id) {
    return from(id).pipe(tap(() => {
     // do some code for each API call
    }));
}

也是一個很大的網站,以了解rxjs - https://www.learnrxjs.io/

暫無
暫無

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

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