banner
Tomorrow

Tomorrow

不骄不躁
twitter

RxJS —— 學習筆記

RxJS 是 Javascript 的響應式編程庫。它使用可觀察的序列來解決異步操作和事件處理。它提供一種核心類型,即 Observable、衛星類型(Observer、Schedulers、Subjects)和受 Array 方法 (map、filter、reduce、every 等)啟發的運算符,以允許處理異步事件作為集合。
ReactiveX 將觀察者模式與迭代器模式以及函數式編程與集合相結合,以滿足對管理事件序列的理想方式的需求。
RxJS 中解決異步事件管理的基本概念是:

  • Observable: 表示未來值或事件的可調用集合的想法。
  • Observer: 是回調的集合,知道如何監聽 Observer 傳遞的值。
  • Subscription: 表示 Observable 的執行,主要用於取消執行。
  • Operators: 運算符,是純函數,支持使用 map、filter、concat、reduce 等操作處理集合的函數式編程風格。
  • Subject: 相當於一個 EventEmitter,是將一個值或事件多播給多個 Observers 的唯一途徑。
  • Schedulers: 調度程序,是控制並發的集中式調度程序,允許我們在計算發生時進行協調,例如 setTimeout 或 requestAnimationFrame 等。

舉個例子
通常你註冊事件監聽器

document.addEventListener('click', () => console.log('Clicked!'));

使用 RxJS,你可以創建一個可觀察者對象

import { fromEvent } from 'rxjs';

fromEvent(document, 'click').subscribe(() => console.log('Clicked!'));

純函數#

使 RxJS 強大的是它的純函數產生值的能力。這意味著你的代碼不太容易出錯。
通常你會創建一個不純的函數,你的代碼的其他部分可能會弄亂你的狀態。

let count = 0;
document.addEventListener('click', () => console.log(`Clicked ${++counts} times`));

使用 RxJS 可以隔離狀態。

import { fromEvent, scan } from 'rxjs';

fromEvent(document, 'click')
	.pipe(scan((count) => count + 1, 0))
	.subscribe((count) => console.log(`Clicked ${++count} times`));

scan 運算符的工作方式與數組 reduce 類似。它接受一個暴露給回調的值。回調的返回值將成為下一次回調運行時的入參。

#

RxJS 擁有一整套操作符,可幫助你控制事件如何流經你的可觀察對象。
這是你允許每秒最多點擊一次的方式,使用純 javascript:

let count = 0;
let rate = 1000;
let lastClick = Date.now() - rate;
document.addEventListener('click', () => {
	if (Date.now() - lastClick >= rate) {
		console.log(`Clicked ${++count} times`);
		lastClick = Date.now();
	}
});

用 RxJS 實現:

import { fromEvent, throttleTime, scan } from 'rxjs';

fromEvent(document, 'click')
	.pipe(
		throttleTime(1000),
		scan((count) => count + 1, 0)
	)
	.subscribe((count) => console.log(`Clicked ${count} times`));

其他流控制運算符還有 filter、delay、debounceTime、take、takeUntil、distinct、distinctUntilChanged 等。

#

你可以轉換通過可觀察者對象的值。
以下是如何在純 javascript 中為每次點擊添加當前滑鼠 x 的位置:

let count = 0;
const rate = 1000;
let lastClick = Date.now() - rate;
document.addEventListener('click', (event) => {
	if (Date.now() - lastClick >= rate) {
		count += event.clientX;
		console.log(count);
		lastClick = Date.now();
	}
})

用 RxJS 實現:

import { fromEvent, throttleTime, map, scan } from 'rxjs';

fromEvent(document, 'click')
	.pipe(
		throttleTime(1000),
		map((event) => event.clientX),
		scan((count, clientX) => count + clientX, 0)
	)
	.subscribe((count) => console.log(count));

其他轉換值的操作符還有 pluck、pairwise、sample 等。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。