RxJS – Custom Operator

前言

雖然 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>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章