前言
雖然 RxJS 提供了非常多的 Operators. 但依然會有不夠用的時候. 這時就可以自定義 Operator 了.
Operator Is Just a Function Observable => Observable
Operator 只是一個函數.
timer(1000).pipe(obs => obs).subscribe();
它接收一個 Observable 返回一個 Observable.
Operator 都是放在管道 (pipe) 內的, 所以從源頭 Observable 一直傳遞下去.
每一個 Operator 接收 upstream(上游) 的 Observable 並且返回一個 Observable (通常是新的一個) 給 downstream(下游).
每一個 Operator 就是對發佈值的加工處理.
Standard Operator
source 源頭
首先我們有個源頭
const source = timer(1000);
每一秒發佈一次
Upstream / Downstream Observable
接着搞一個 pipe 和 operator.
const source = timer(1000); source .pipe(upstreamObs => { console.log(upstreamObs === source); // true const downstreamObs = new Observable(); return downstreamObs; }) .subscribe(v => console.log(v));
可以看到 operator 函數接收的就是 upstream 的 Observable, 然後返回一個新的 Observable 到 downstream.
Connect Upstream and Downstream
downstream to upstream
當 downstream 被 subscribe, 我們 subscribe upstream
當 downstream 被 unsubscribe, 我們 unsubscribe upstream
const source = timer(1000); source .pipe(upstreamObs => { const downstreamObs = new Observable(subscriber => { // 當 downstream Observable 被訂閱以後, 我們才訂閱 upstream Observable const upstreamSub = upstreamObs.subscribe(); return () => { // 當 downstream 被退訂以後, 我們也要退訂 upstream Observable upstreamSub.unsubscribe(); }; }); return downstreamObs; }) .subscribe(v => console.log(v));
upstream to downstream
當接收到 upstream 發佈時, 我們也發佈到 downstream
const downstreamObs = new Observable(subscriber => { const upstreamSub = upstreamObs.subscribe(upstreamValue => { const downStreamValue = upstreamValue + 'downstream value'; // decorate value for downstream subscriber.next(downStreamValue); // 發佈到 downstream }); return () => { upstreamSub.unsubscribe(); }; });
小結
從上面幾招可以看出來, 主要就是 upstream 和 downstream 中間的關係.
如何訂閱, 退訂, 發佈 value 等等. 上面只是給一個簡單直觀的例子. 真實場景中, upstream 和 downstream 發佈時機, 往往是不一致的 (比如 upstream 發佈 1 次後, downstream 可能發佈多次)
Operator with Config
只要把 Operator 包裝成工廠函數就可以支持 Config 了
function myOperator(config: string): OperatorFunction<number, string> { console.log(config); return upstreamObs => { const downstreamObs = new Observable<string>(subscriber => { const upstreamSub = upstreamObs.subscribe(upstreamValue => { const downStreamValue = upstreamValue + 'downstream value'; // decorate value for downstream subscriber.next(downStreamValue); // 發佈到 downstream }); return () => { upstreamSub.unsubscribe(); }; }); return downstreamObs; }; } const source = timer(1000); source.pipe(myOperator('some config here...')).subscribe(v => console.log(v));
一個 Factory 函數, 通過配置生產 Operator.
OperatorFunction 定義了 Operator 接口, 它是加入了泛型的 Observable => Observable.
如果 upstream 和 downstream 的類型是一樣的話可以用它的簡化版本 MonoTypeOperatorFunction<T>