iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
1
Modern Web

ngrx/store 4 學習筆記系列 第 4

[ngrx/store - 4] 多重資料流的 Operators

多重資料流的 Operators

concat

在多重資料流下,concat 會依次做完一個個 Observable,產生一個新的 Observable

var timer = Rx.Observable.interval(1000).take(4);
var sequence = Rx.Observable.from(['a', 'b', 'c','d']);

var result = timer.concat(sequence);
result.subscribe(x => console.log(x));

這裡 timer.concat(sequence), 所以會先做完 timer, 再做 sequence
印出 0,1,2,3,a,b,c,d, 即使 timer 是一秒產生出一個值,concat 會等 timer take(4) 完,才一次印出 a, b, c, d

反過來,如果用 sequence.concat(timer), 結果當然會是馬上印出a,b,c,d,0然後在一秒印出一個值,直到 1,2,3, concat 的參數可以超過一個以上。

var timer = Rx.Observable.interval(1000).take(4);
var sequence = Rx.Observable.from(['a', 'b', 'c','d']);

var result = sequence.concat(timer);
result.subscribe(x => console.log(x));

merge

用 merge 的話就沒有這種紀律,先碰到的資料就先處理

var timer = Rx.Observable.interval(1000).take(4);
var sequence = Rx.Observable.from(['a', 'b', 'c','d']);

var result = timer.merge(sequence);
result.subscribe(x => console.log(x));

即使是 timer.merge(sequence), 因為 timer 還要等一秒鐘,所以會直接印出 a, b, c, d, 0, 1, 2, 3

combineLatest

combineLatest 處理當兩個 Observable 資料都有變動時,拿最後的資料來產生一個新的 Observable

var timer = Rx.Observable.interval(1000).take(4);
var sequence = Rx.Observable.from(['a', 'b', 'c','d']);

var result = timer.combineLatest(sequence, (t,s) => ({t, s}));
result.subscribe(x => console.log(x));

結果會是 {0, d}, {1, d}, {2, d}, {3, d}因為等 timer 產生第一個值時, sequence 已經做完了,所以叫 combineLatest,那如果我們希望一對一配對產生新的 Observable,而不管時間發生的順序呢?

zip

zip 也就是處理當兩個 Observable 的資料有所變動時,如果有時間差,它會將值保留,再將他們一一配對產生新的 Observable

var timer = Rx.Observable.interval(1000).take(4);
var sequence = Rx.Observable.from(['a', 'b', 'c','d']);

var result = timer.zip(sequence, (t,s) => ({t, s}));
result.subscribe(x => console.log(x));

https://ithelp.ithome.com.tw/upload/images/20171220/2010357474kSO9tcnk.png
如圖所示,結果會是 {a, 0}, {b, 1}, {c, 2}, {d, 3}, combineLatest 跟 zip 的第二個參數稱為 project function, 也就是產生新的 Observable 時資料的格式,如果不設的話預設值會是一個陣列

forkJoin

如果不管兩個 Observable 中間產生的資料,只要等最後的結果,可以用 .forkJoin, 這是相當於 Promise.all,用在對後端的request 時,如果要等兩個 Observable 都做完,可以用的 Operator,但要小心的是,如果其中之一沒完成是不會產生 Observable 的,所以實作時,務必要做 error handling.

var timer = Rx.Observable.interval(1000).take(4);
var sequence = Rx.Observable.from(['a', 'b', 'c','d']);

var result = Rx.Observable.forkJoin(timer, sequence);
result.subscribe(x => console.log(x));

印出的結果會是 [3, 'd']

以上程式請參考 codepen

下次我們來看高階(High Order) Observable 的 Operators


上一篇
[ngrx/store -3] Observable 的 運算子 (Operator)
下一篇
[ngrx/store -5] 高階 (High Order) Observable
系列文
ngrx/store 4 學習筆記30

尚未有邦友留言

立即登入留言