Skip to main content

[note] RxJS 筆記

TL;DR;#

  • Observable 會發送資料給 Observer,但它只管傳遞資料,並不會去管 Subscribers 拿資料去做什麼。
import { fromEvent } from 'rxjs';
const button = document.getElementById('my-button');
// 建立 button click 的 observable
const myObservable = fromEvent(button, 'click');
// observable 推資料給 observer
const subscription = myObservable.subscribe((event) => console.log(event));

重要概念#

  • Observable:可被觀察的物件,未來可以被執行的值或事件
  • Observer:一系列的 callback,這些 callback 知道如何監聽由 Observable 傳來的值
  • Subscription:Observable 的執行,主要用來取消執行(cancel execution)
  • Operators:用來操作由 observable 傳過來的資料,例如,map, filter, concat, reduce
  • Subject:等同於 EventEmitter,是唯一一種用來群播/多播(multicast)值或事件給其他 Observer 的方式
  • Schedulers:中央的 dispatcher,用來控制 concurrency,例如 setTimeoutrequestAnimationFrame

Operators#

當 Observable 傳來資料後,在資料傳遞給 Observer 之前,可以透過 Operators 針對資料進行處理。Operators 可以分成幾類:

  • Creation operators:可以將幾乎所有東西變成 observable。常見的像是 of, from, formEvent
  • Combination operators:可以一次收集來自多個 obserable 的資料。常見的像是 combineLatest, concat, merge, startWithwithLatestFrom
  • Error handling operators:用來處理錯誤,重試請求等。最常見的是 catchError
  • Filtering operators:用來過濾資料。例如 debounceTime, distinctUntilChanged, filter, take, takeUntil
  • Multicating operators:預設的情況下,RxJS 的 observable 是 cold / unicast 的,也就是一個 observable 只會有一個 subscriber。透過 multicating operators 可以讓 obserable 變成 hot / multicasting 的,可以將資料傳給多個 subscribers。最常見的是 shareReplay
  • Transformation operators:用來轉換資料,常見的如 concatMap, map, mergeMap, scanswitchMap

Creation#

of#

以一個一個參數的方式帶入資料:

import { of } from 'rxjs';
//emits any number of provided values in sequence
const source = of(1, 2, 3, 4, 5);

from#

以一個陣列的方式當作參數帶入資料:

  • 可以用來處理 Promise
import { from } from 'rxjs';
//emit array as a sequence of values
const arraySource = from([1, 2, 3, 4, 5]);

Utility#

tap / do#

直接在該 pipeline 時把值取出:

// https://www.learnrxjs.io/learn-rxjs/operators/utility/do#examples
import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';
const source = of(1, 2, 3, 4, 5);
// transparently log values from source with 'tap'
const example = source.pipe(
tap(val => console.log(`BEFORE MAP: ${val}`)),
map(val => val + 10),
tap(val => console.log(`AFTER MAP: ${val}`))
);

可以接收物件當作參數,tap({next, error, complete})

// https://www.learnrxjs.io/learn-rxjs/operators/utility/do#examples
import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';
const source = of(1, 2, 3, 4, 5);
// tap also accepts an object map to log next, error, and complete
const example = source
.pipe(
map(val => val + 10),
tap({
next: val => {
// on next 11, etc.
console.log('on next', val);
},
error: error => {
console.log('on error', error.message);
},
complete: () => console.log('on complete')
})
)
Last updated on