前言
在Rxjs的世界中,爲了滿足複雜的需求,往往需要把不同來源 的數據匯聚在一起,把多個Observable對象的數據合併到一個 Observable對象中。
合併類操作符
- concat
能夠把多個Observable中的數據 內容依次合併。
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/concat';
const source1$ = Observable.of(1, 2, 3);
const source2$ = Observable.of(4, 5, 6);
const concated$ = source1$.concat(source2$);
- Merge
merge會第一時間訂閱所有的上游Observable,然 後對上游的數據採取“先到先得”的策略,任何一個Observable只要有數據推 下來,就立刻轉給下游Observable對象。
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/timer';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/merge';
const source1$ = Observable.timer(0, 1000).map(x => x+'A');
const source2$ = Observable.timer(500, 1000).map(x => x+'B');
const merged$= Observable.merge(source1$, source2$);
merged$.subscribe(
console.log,
null,
() => console.log('complete')
);
- zip
一對一合併。
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/zip';
const source1$ = Observable.of(1, 2, 3);
const source2$ = Observable.of('a', 'b', 'c');
const zipped$ = Observable.zip(source1$, source2$);
zipped$.subscribe(
console.log,
null,
() => console.log('complete')
);
zip又和concat、merge很不同, concat、merge會保留原有的數據傳給下游,但是zip會把上游的數據轉化爲 數組形式,每一個上游Observable貢獻的數據會在對應數組中佔一席之地。
- combineLatest
合併最後一個數據。
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/timer';
import 'rxjs/add/operator/combineLatest';
import 'rxjs/add/operator/map';
const source1$ = Observable.timer(500, 1000);
const source2$ = Observable.timer(1000, 1000);
const result$ = source1$.combineLatest(source2$);
result$.subscribe(
console.log,
null,
() => console.log('complete')
);
ombineLatest合併數據流的方式是當任何一個上游Observable產生數據 時,從所有輸出Observable對象中拿最後一次產生的數據(最新數據),然後把這些數據組合起來傳給下游。
- withLatestFrom
withLatestFrom的功能類似於combineLatest,但是給下游推送數據只能 由一個上游Observable對象驅動。
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/timer';
import 'rxjs/add/operator/withLatestFrom';
import 'rxjs/add/operator/map';
const source1$ = Observable.timer(0, 2000).map(x => 100 * x);
const source2$ = Observable.timer(500, 1000);
const result$ = source1$.withLatestFrom(source2$, (a,b)=> a+b);
result$.subscribe(
console.log,
null,
() => console.log('complete')
);
- race
多個Observable對象在一起,看誰最先產生數據,就選擇使用誰。
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/timer';
import 'rxjs/add/operator/race';
import 'rxjs/add/operator/map';
const source1$ = Observable.timer(0, 2000).map(x => x+'a');
const source2$ = Observable.timer(500, 1000).map(x => x+'b');
const winner$ = source1$.race(source2$);
winner$.subscribe(
console.log,
null,
() => console.log('complete')
);
高階observable
高階observable是Observable來管理多個Observable 對象。Rxjs擅長處理複雜的數據操作問題,這些問題往往需要涉及多個數據 流,Rxjs將數據流也看做Observable。用現 成的管理Observable對象的方法來管理Observable對象,這就是高階 Observable的意義。
- concatAll
concat是把所有輸入的Observable首尾相連組合在一起,concatAll做的事情也一樣,只不過concatAll只有一個上游Observable對 象,這個Observable對象預期是一個高階Observable對象,concatAll會對其 中的內部Observable對象做concat。
const ho$ = Observable.interval(1000)
.take(2)
.map(x => Observable.interval(1500).map(y => x+':'+y).take(2));
const concated$ = ho$.concatAll();
- mergeAll
mergeAll就是處理高階Observable的merge,只是所有的輸入Observable 來自於上游產生的內部Observable對象。
const ho$ = Observable.interval(1000)
.take(2)
.map(x => Observable.interval(1500).map(y => x+':'+y).take(2));
const concated$ = ho$.mergeAll();
- zipAll
在Rxjs的官方文檔中,這個操作符幾乎沒有文檔,實際上,如果你能 夠理解zip,也能夠理解前面介紹的concatAll和mergeAll,那麼自然就能夠理解zipAll。
const ho$ = Observable.interval(1000)
.take(2)
.map(x => Observable.interval(1500).map(y => x+':'+y).take(2));
const concated$ = ho$.zipAll();
- combineAll
combineAll就是處理高階Observable的combineLatest,可能是因爲 combine-LatestAll太長了,所以Rxjs選擇了combineAll這個名字。
const ho$ = Observable.interval(1000)
.take(2)
.map(x => Observable.interval(1500).map(y => x+':'+y).take(2));
const concated$ = ho$.combineAll();
總結
本文記錄了Rxjs中合併多個Observable對象的用法。不同合併用法的 區別在於用何種策略把上游多個Observable對象中數據轉給下游產生的數據依然是Observable對象的Observable,稱爲高階 Observable,Rxjs提供了合併高階Observable對象中數據的操作符,實際上 只是把多個Observable對象參數改成了一個高階Observable對象。