在多重資料流下,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 的話就沒有這種紀律,先碰到的資料就先處理
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 處理當兩個 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 也就是處理當兩個 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));
如圖所示,結果會是 {a, 0}, {b, 1}, {c, 2}, {d, 3}
, combineLatest 跟 zip 的第二個參數稱為 project function, 也就是產生新的 Observable 時資料的格式,如果不設的話預設值會是一個陣列
如果不管兩個 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