RxJS合並操作符:concat、merge、forkJoin、zip、 combineLatest 、concatAll、mergeAll、switchAll


forkJoin

forkJoin合並的流,會在每個被合並的流都發出結束信號時發射一次也是唯一一次數據。 即所有的流都complete或者error時才會發射一次數據。

zip

zip工作原理如下,當每個傳入zip的流都發射完畢第一次數據時,zip將這些數據合並為數組並發射出去;當這些流都發射完第二次數據時,zip再次將它們合並為數組並發射。以此類推直到其中某個流發出結束信號,整個被合並后的流結束,不再發射數據。

zipforkJoin的區別在於,forkJoin僅會合並各個子流最后發射的一次數據,觸發一次回調;zip會等待每個子流都發射完一次數據然后合並發射,之后繼續等待,直到其中某個流結束(因為此時不能使合並的數據包含每個子流的數據)。

combineLatest

combineLatestzip很相似,combineLatest一開始也會等待每個子流都發射完一次數據,但是在合並時,如果子流1在等待其他流發射數據期間又發射了新數據,則使用子流最新發射的數據進行合並,之后每當有某個流發射新數據,不再等待其他流同步發射數據,而是使用其他流之前的最近一次數據進行合並。

concat

按照順序,前一個 observable 完成(complete)了再訂閱下一個 observable 並發出值 。即前一個observable發出complete信號后,才會訂閱下一個observable。

merge

merge 把多個 observable 同時處處理, 當多個 observable 其中一個被觸發時都可以被處理,這很常用在一個以上的按鈕具有部分相同的行為。

例如一個影片播放器有兩個按鈕,一個是暫停(II),另一個是結束播放(口)。這兩個按鈕都具有相同的行為就是影片會被停止,只是結束播放會讓影片回到 00 秒,這時我們就可以把這兩個按鈕的事件 merge 起來處理影片暫停這件事。

concatAll、mergeAll、switchAll屬於高階 Observable 的 操作符。都是用來打平Observable的。

所謂的 Higher Order Observable 就是指一個 Observable 發送出的元素還是一個 Observable,就像是二維數組一樣,一個數組中的每個元素還是數組。

如果用TypeScript中的泛型來表達就像是Observable<Observable<T>>,通常我們需要的是第二層 Observable 送出的元素,所以我們希望可以把二維的 Observable 改成一維的,像是下面這樣 Observable<Observable<T>> => Observable<T>

concatAll

處理完前一個 observable 才會在處理下一個 observable。依次按順序執行一個個observable

switchAll

新的 observable 送出后直接處理新的 observable 不管前一個 observable 是否完成,每當有新的 observable 送出就會直接把舊的 observable 退訂(unsubscribe),永遠只處理最新的 observable!

mergeAll

並且能夠同時並行處理所有的 observable

看下面的例子,我們可以切換為 concatAll,mergeAll,switchAll 體驗區別

const example = fromEvent(document.body, 'click')
    .pipe(
      // map 把送出的event事件轉換為 Observable
      // 每次點擊送出一個新的 Observable
      map(e => {
        // console.log(e);
        // 生成新的 Observable,點擊一次輸出0,1,2
        return interval(1000).pipe(take(3))
      }),
     
     // concatAll 比如快速點擊三次,會按順序輸出三次0,1,2
     // switchAll 快速點擊,只輸出一次0,1,2,也就是說老的舍去只保留最新的
     // mergeAll 快速點擊,會重復的輸出多次0,1等。點擊越多下,最后送出的頻率就會越快。不會舍去,每次都會輸出
      switchAll()
    );


  example.subscribe({
    next: (value) => { console.log(value); },
    error: (err)  => { console.log('Error: ' + err); },
    complete: ()  => { console.log('complete'); }
  });


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM