forkJoin
1.特點:在每個被合并的流都發(fā)出complete信號時锚烦,發(fā)射一次也是唯一一次數(shù)據(jù)拆魏;
const ob1 = Rx.Observable.interval(1000).map(d => `ob1:$qqcsscc`).take(3);
const ob2 = Rx.Observable.interval(2000).map(d => `ob2:$8oyq0su`).take(2);
Rx.Observable.forkJoin(ob1, ob2).subscribe((data) => console.log(data));
// ["ob1:2", "ob2:1"]:ob1在發(fā)射完第三個數(shù)據(jù)時發(fā)出complete信號鹏倘,ob2在發(fā)射完第二個數(shù)據(jù)時發(fā)射出complete信號,forkJoin等ob1和ob2都結(jié)束時發(fā)射一次數(shù)據(jù)绰寞;
2.適用場景:有一組流,當(dāng)你只關(guān)心每個流的最終發(fā)射值铣口,即這種序列只有一次發(fā)射 — 類似 Promise.all()
(1)對于一個發(fā)出多個值的流滤钱,除了最后發(fā)出的一個值之外,其他的值都會忽略脑题;
(2)當(dāng)所有內(nèi)部流完成時件缸,生成的流只發(fā)出一次 — 如果任何內(nèi)部流沒有完成,它將永遠(yuǎn)不會完成叔遂,如果任何內(nèi)部流出錯他炊,它將拋出一個錯誤争剿;
zip
1.特點:當(dāng)每個被合并的流都發(fā)射了新數(shù)據(jù),zip將其合并為數(shù)組發(fā)射出去佑稠,直到其中某個流發(fā)出complete信號秒梅,整個被合并的流結(jié)束不再發(fā)射數(shù)據(jù);
const ob1 = Rx.Observable.interval(1000).map(d => `ob1:$qwwowcm`).take(3);
const ob2 = Rx.Observable.interval(2000).map(d => `ob2:$em60soc`).take(2);
Rx.Observable.zip(ob1, ob2).subscribe({
next: (data) => console.log(data),
complete: () => console.log('complete')
});
// ["ob1:0", "ob2:0"] ob1等待ob2發(fā)射數(shù)據(jù)舌胶,之后合并
// ["ob1:1", "ob2:1"] 此時ob2結(jié)束捆蜀,整個合并的流也結(jié)束
// "complete"
2.適用場景:有一組流,當(dāng)你關(guān)心這一組流的最新發(fā)射值集合幔嫂,即它等待從所有輸入流中發(fā)出相應(yīng)的值辆它,然后將它們轉(zhuǎn)換成單個值數(shù)組并發(fā)出結(jié)果;
(1)只有當(dāng)每個源序列中有一對新值時履恩,它才會發(fā)布锰茉,因此如果其中一個源序列發(fā)布值的速度快于另一個序列,發(fā)布速率將由兩個序列中較慢的一個決定切心;
(2)當(dāng)任何內(nèi)部流完成并且相應(yīng)的匹配對從其他流發(fā)出時飒筑,結(jié)果流完成。如果任何內(nèi)部流沒有完成绽昏,它將永遠(yuǎn)不會完成协屡,如果任何內(nèi)部流出錯,它將拋出一個錯誤全谤;
combineLatest
1.特點:第一次等待被合并的流發(fā)出新數(shù)據(jù)肤晓,但在合并時,若其中有流在等待其他流發(fā)射數(shù)據(jù)期間又發(fā)射了新數(shù)據(jù)认然,則使用該流的新數(shù)據(jù)進行合并补憾,之后只要某個流發(fā)射新數(shù)據(jù),不再等待其他流同步發(fā)出數(shù)據(jù)卷员,而是使用其他流的最近一次數(shù)據(jù)進行合并盈匾,直至所有數(shù)據(jù)發(fā)出complete信號;
const ob1 = Rx.Observable.interval(1000).map(d => `ob1:$66eua6q`).take(3);
const ob2 = Rx.Observable.interval(2000).map(d => `ob2:$8wucsum`).take(2);
Rx.Observable.combineLatest(ob1, ob2).subscribe({
next: (data) => console.log(data),
complete: () => console.log('complete')
});
// ["ob1:1", "ob2:0"] ob1等待ob2發(fā)射毕骡,當(dāng)ob2發(fā)射時ob1已經(jīng)發(fā)射了第二次數(shù)據(jù)削饵,使用ob1的第二次數(shù)據(jù)
// ["ob1:2", "ob2:0"] ob1繼續(xù)發(fā)射第三次也是最后一次數(shù)據(jù),ob2雖然還未發(fā)射挺峡,但是可以使用它上一次的數(shù)據(jù)
// ["ob1:2", "ob2:1"] ob2發(fā)射第二次也是最后一次數(shù)據(jù)葵孤,使ob1上一次的數(shù)據(jù)。
// "complete"
2.適用場景:有一組流橱赠,當(dāng)你關(guān)心這一組流的任一一個流的最新發(fā)射值尤仍,即需要在部分狀態(tài)發(fā)生變化時保持最新;
(1)RxJs緩存每個輸入序列的最后一個值狭姨,一旦所有序列產(chǎn)生了至少一個值宰啦,它就使用從緩存中獲取各個流當(dāng)前的最新值來計算結(jié)果值苏遥,然后通過結(jié)果流發(fā)出該計算的輸出;
(2)如果某個輸入流不發(fā)出任何值并且永遠(yuǎn)不會完成赡模,combineLatest也永遠(yuǎn)不會發(fā)出并且永遠(yuǎn)不會完成田炭,因為它將再次等待所有流中某個流發(fā)出某個值;
【總結(jié)】:forkJoin僅會合并各個子流最后發(fā)射的一次數(shù)據(jù)漓柑,觸發(fā)一次回調(diào)教硫;zip是只要被合并的流均發(fā)射了新數(shù)據(jù)則將其合并發(fā)射,之后繼續(xù)等待至某個流結(jié)束辆布;combineLatest是只要被合并的流有一個發(fā)射新數(shù)據(jù)則將發(fā)射合并數(shù)據(jù)瞬矩,直至所有流結(jié)束;