# Observable Operators & Marble Diagrams

# 什麼是 Operator

Operators 就是一個個被附加到 Observable 型別的函式,例如像是 map、filter、contactAll... 等等,所有這些函式都會拿到原本的 observable 並回傳一個 新的 observable

實作 map operator

const people = rxjs.of('Jerry', 'Anna');

function map(source, callback) {
  // 新增一個新的 observable 並回傳
  return rxjs.Observable.create((observer) => {
    // 訂閱原本的 observable
    return source.subscribe(
      (value) => {
        try {
          observer.next(callback(value));
        } catch (e) {
          observer.error(e);
        }
      },
      (error) => observer.error(error),
      () => observer.complete()
    );
  });
}

const helloPeople = map(people, (item) => item + ' Hello!');
helloPeople.subscribe(console.log);

// 結果:
// Jerry Hello!
// Anna Hello!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

重點

  1. 每個 operator 都會回傳一個新的 observable
  2. 我們可以透過 create 的方法建立各種 operator

# Marble diagrams

訂定 observable 的圖示,就能讓我們更方便的溝通及理解 observable 的各種 operators,先行採取 ASCII 的繪畫方式

  • - 來表達一小段時間,這些 - 串起就代表一個 observable
----------------
1
  • X (大寫 X)則代表有錯誤發生
---------------X
1
  • | 則代表 observable 結束
----------------|
1

interval 舉例

const source = rxjs.interval(1000);
1

source 的圖形就會長像這樣

-----0-----1-----2-----3...
1

以同步送值為例

const source = rxjs.of(1, 2, 3, 4);
1

source 的圖形就會長像這樣,小括號 代表著同步發生

(1234)|
1

# operator 的前後轉換

const source = rxjs.interval(1000);
// 利用剛剛的自訂的 map
const newest = map(source, (x) => x + 1);
1
2
3

source 的圖形就會長像這樣

最上面是原本的 observable,中間是 operator,下面則是新的 observable

source: -----0-----1-----2-----3--...
            map(x => x + 1)
newest: -----1-----2-----3-----4--...
1
2
3

Marble Diagrams 相關資源: http://rxmarbles.com/

# map

Observable 的 map 方法使用上跟陣列的 map 是一樣的,我們傳入一個 callback function,這個 callback function 會帶入每次發送出來的元素,然後我們回傳 新的元素

const source = rxjs.interval(1000);
const newest = source.pipe(rxjs.operators.map((x) => x + 2));
1
2

Marble diagrams 表達:

source: -----0-----1-----2-----3--...
            map(x => x + 1)
newest: -----1-----2-----3-----4--...
1
2
3

# mapTo

可以把傳進來的值改成一個固定的值

const source = rxjs.interval(1000);
const newest = source.pipe(rxjs.operators.mapTo('Hello!'));
1
2

Marble diagrams 表達:

source: -----0-----1-----2-----3--...
            mapTo('Hello!')
newest: -----Hello!-----Hello!-----Hello!-----Hello!--...
1
2
3

# filter

filter 在使用上也跟陣列的相同,我們要傳入一個 callback function,這個 function 會傳入每個被送出的元素,並且回傳一個 boolean 值,如果為 true 的話就會保留,如果為 false 就會被濾掉

const source = rxjs.interval(1000);
const newest = source.pipe(rxjs.operators.filter((x) => x % 2 === 0));
1
2

Marble diagrams 表達:

source: -----0-----1-----2-----3-----4...
            filter((x) => x % 2 === 0)
newest: -----0----------2----------4...
1
2
3

# 參考

30 天精通 RxJS (07): Observable Operators & Marble Diagrams (opens new window)

Last Updated: 2021/2/25 上午8:00:30