High Obser Observable
在 Javascript 中,陣列中除了純量(number, string…) 外,也可以有陣列,在物件中也可以有物件,那 Observable 觀察的資料流當然也可以是一些 Observables. 這樣的 Observable 我們稱為高階 (High Order) Observable, 舉個例子
const numObservable = new Rx.Observable.create(observer => {
observer.next(1);
setTimeout(() => observer.next(3), 2000);
setTimeout(() => observer.next(5), 3000);
});
const highObservable = numObservable.map(v => Rx.Observable.of(v*10));
highObservable
.subscribe(
x => x.subscribe(
y => console.log(“from inner: “, y)
)
);
會簡單印出from inner: 10, from inner: 30, from inner: 50
第一個 numObservable 又稱為 outer Observable,它先觸發一個 1,兩秒後觸發 3, 第三秒觸發 5.
當 outer Observable 發出新資料時,會丟到 inner Observable Rx.Observable.of(v*10),將產生新的資料乘 10
所以當 subscribe 時會有兩個 subscribe, 第一個是外圈 outer Observable 的 subscribe, 第二個才是內圈的 subscribe
這樣做當然有點麻煩,所以有一些 Operator 可以幫助我們簡化這個 subscribe,例如
const numObservable = new Rx.Observable.create(observer => {
observer.next(1);
setTimeout(() => observer.next(3), 2000);
setTimeout(() => observer.next(5), 3000);
});
numObservable.mergeMap(v => Rx.Observable.of(v*10))
.subscribe(x => console.log(“from mergeMap: “,x));
跟上面的結果會是一樣的,當然這些強大的 Operator 功能不只如此,我們來介紹第一個 Operator
mergeMap (flatMap)
上面的例子中 outer Observable 觸發三次,所以會產生三個 inner Observable, mergeMap 或者以前稱為 flatMap 的意思就是將這些 inner Observables 結合在一起,或者說將它們攤平(flat) 產生一個新的 Observable, 再舉一個例子
const numObservable = new Rx.Observable.create(observer => {
observer.next(1);
setTimeout(() => observer.next(3), 2000);
setTimeout(() => observer.next(5), 3000);
});
numObservable.mergeMap(v => Rx.Observable.interval(500).take(3), (v, i) => v * 10)
.subscribe(x => console.log(“from mergeMap: “, x));
它會印出
numObservable 跟上面一樣
inner Observable 收到資料後,會半秒鐘會觸發一次動作,總共做 3 次
mergeMap 的第二個參數是一個函數, 可以帶 Outer 跟 inner Obervable 的值再加工,這裡我們將 Outer Observable 的值乘 10
注意到當第一個 50 產生後,前面的最後一個 30 因為時間差才印出來
switchMap
switchMap 跟 mergeMap 一樣將 inner Observables 結合成一個新的 Observable,但是在 Outer Observable 觸發新的資料後,原先的 inner Observable 就會被 cancel 掉,看以下的例子
const numObservable = new Rx.Observable.create(observer => {
observer.next(1);
setTimeout(() => observer.next(3), 2000);
setTimeout(() => observer.next(5), 3000);
});
numObservable.switchMap(v => Rx.Observable.interval(500).take(3), (v, i) => v * 10)
.subscribe(x => console.log(“from switchMap: “, x));
結果會是
concatMap
最後當然有 concatMap, 就像 concat 一樣,他會很有紀律的依次做完每一個 inner Observable
const numObservable = new Rx.Observable.create(observer => {
observer.next(1);
setTimeout(() => observer.next(3), 2000);
setTimeout(() => observer.next(5), 3000);
});
numObservable.concatMap(v => Rx.Observable.interval(500).take(3), (v, i) => v * 10)
.subscribe(x => console.log(“from concatMap: “, x));
會完整且依序印出
這些 High Order Operator 對 ngrx/store 很重要,特別是在做 effect 時,我們通常要透過 Angular 的 HttpClient 來接後端的資料。而 HttpClient 回傳的就是一個 Observable. 所以當一個 Store 的 Action (也是 Observable) 要處理 HttpClient (Observable)時,就會用到這些 Operator.
還有這些 High Order Operator 的 inner Observable 也可以是 Promise,所以才說這些是強大的 Operator 群。
ngrx/store 代表了三個主題, ng 是 Angular, rx 是 RxJS, 也就是這幾天談的 Observable 的部分,接下來,讓我們來仔細看一下 store 的部分,也就是 Flux(Redux) 的基礎介紹
转载请注明:XAMPP中文组官网 » 高階 (High Order) Observable