[note] RxJS 筆記
本篇內容大量整理自 RxJS 7 and Observables: Introduction @ Udemy。另外,由於 Operators 的種類眾多,建議可以搭配 Learn RxJS 和 RxJS Guide 學習。
TL;DR;
Observable 會發送資料給 Observer,但它只管傳遞資料,並不會去管 Subscribers 拿資料去做什麼。
import { Observable, Observer } from 'rxjs';
const observable$ = new Observable()<string>((subscriber) => {
// Next
subscriber.next('foo');
// Error
subscriber.error(new Error('some error occurred'));
// Complete
subscriber.complete();
// Teardown
return () => {
console.log('observable teardown');
};
});
const observer: Observer<string> = {
next: (value: string) => console.log(value),
complete: () => console.log('complete'),
error: (err: Error) => console.log(err.message),
};
const subscription = observable$.subscribe(observer);
// 如果只需要 next handler 可以在參數的地方直接帶入 function 而非帶入物件
// const subscriptionWithOnlyNextHandler = observable$.subscribe((value: string) =>
// console.log(value),
// );
// 如果對於 Observable 提供的值不在感興趣,要 unsubscribe
subscription.unsubscribe();
常用的 Transformation Operator:
concatMap
:一次一個,依序執行,前一個完成後下一個才會接著執行。是最安全的方式,可以避免 memory leak,前一次的 observable 被取消,或沒有依照 request 的順序處理 response,但也因此可能比較沒效率。switchMap
:當 inner observable 有新的 emit value 是,會取消(cancel)前一次的 inner subscription,也就是說,一次只會有一個最新的 inner subscription 在進行,總是會拿到最新的順序。mergeMap
:以併發的方式執行多個 inner subscription,且不會確保 response 被處理的順序,先 complete 的 inner subscription 會先往後 notify。
重要概念
Observables
Array vs Stream
- array 在一開始就會被定義好裡面有哪些資料,開發者對於 array 中有哪些元素存在可以一目瞭然
- stream 中的項目(items)則可能會在不同的時間點產生,stream 有時間的概念在內,開發者不知道下一個時間點會得到什麼資料,但可以先寫好當某個項目出現是對應要執行的程式邏輯,這也是 reactive programming 的概念
- 在 JavaScript 中的許多事件都可以用 stream 的角度來思考,例如使用者輸入資料時,我們不知道下個時間點會得到什麼資料,但可以先把當資料進來後的邏輯寫好;HTTP Response 的事件等等也是類似的概念。