本文結構:
- 什么是
RxJS
-
RxJS
有什么特點 -
RxJS
核心概念
什么是RxJS
在javaScript中,我們可能會經常接觸到類似于回調函數、Promise、Gender、async函數等異步編程方式,雖然以上的方式各有各的特點,但是我們需要更加強大的特性和更加優雅的寫法.因此RxJS便是我們更好的選擇.
Rx.JS
是英文 Reactive Extensions for JavaScript
的縮寫.翻譯成中文就是: JavaScript的響應式擴展.其主要的功能就是利用響應式編程的模式來實現JavaScript的異步式編程.
RxJS有什么特點
根據官方文檔的介紹:
先寫個簡單的例子,注冊事件監聽器(事件代理):
var button = document.querySelector('button');
button.addEventListener('click', () => console.log('Clicked!'));
咱們用RxJS來實現這個功能(必須要引入Rxjs):
var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
.subscribe(() => console.log('Clicked!'));
以上代碼大家應該是能看懂的,大概解釋一下. Rx.Observable.fromEvent()
相當于創建了一個可觀察對象Observable
,也就是監聽的代理對象,subscribe是這個對象的一個方法,該方法返回這個監聽的事件,subscribe
方法的參數是對觀察對象返回值做出下一步操作(回調函數).
接下來介紹RxJS的特點:
純凈性
先看反面例子:
var count = 0;
var button = document.querySelector('button');
button.addEventListener('click', () => console.log(`Clicked ${++count} times`));
count作為一個全局變量,污染了全局環境,把應用狀態搞的一團糟
下面是正面例子:
var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
.scan(count => count + 1, 0)
.subscribe(count => console.log(`Clicked ${count} times`));
scan
操作符的工作原理與數組的 reduce
類似。
每次回調函數運行后的返回值會作為下次回調函數運行時的參數.
流動性 (Flow)
反面例子:
var count = 0;
var rate = 1000;
var lastClick = Date.now() - rate;
var button = document.querySelector('button');
button.addEventListener('click', () => {
if (Date.now() - lastClick >= rate) {
console.log(`Clicked ${++count} times`);
lastClick = Date.now();
}
}); //實現控制一秒鐘內最多點擊一次
正面教材:
var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
.throttleTime(1000)
.scan(count => count + 1, 0)
.subscribe(count => console.log(`Clicked ${count} times`));
這下覺得RxJS 用起來挺清爽的吧
RxJS核心概念
Observable
(可觀察對象): 表示一個概念,這個概念是一個可調用的未來值或事件的集合。Observer
(觀察者): 一個回調函數的集合,它知道如何去監聽由 Observable 提供的值。Subscription
(訂閱): 表示 Observable 的執行,主要用于取消 Observable 的執行。
Operators
(操作符): 采用函數式編程風格的純函數 (pure function),使用像 map、filter、
concat、flatMap 等這樣的操作符來處理集合。Subject
(主體): 相當于 EventEmitter,并且是將值或事件多路推送給多個 Observer 的唯一方式。Schedulers
(調度器): 用來控制并發并且是中央集權的調度員,允許我們在發生計算時進行協調,例如 setTimeout 或 requestAnimationFrame 或其他。
Observable (可觀察對象)
Observables 是多個值的惰性推送集合
Observable
是RxJS的核心概念之一.它實際上就是可以被外界觀察的一個對象.當本身的狀態發生變化時,就會將其變化推送給外界觀察它的對象,也就是 觀察者對象.同時因為Observables
是多個值的惰性推送集合所以只有當使用一個觀察者對象去訂閱了它之后.它才會同步或異步地返回零到(有可能的)無限多個值.下面是使用RxJS
創建一個Observable
的方式
var observable = Rx.Observable.create(function subscribe(observer) {
var id = setInterval(() => {
observer.next('hi')
}, 1000);
});
上面實例創建了一個 Observable,它每隔一秒會向觀察者發送字符串 'hi'.
Observer (觀察者)
什么是觀察者? - 觀察者是由 Observable 發送的值的消費者。觀察者只是一組回調函數的集合,每個回調函數對應一種 Observable 發送的通知類型:next、error 和 complete 。
簡單來說,Observer就是使用Observable發送出來值的一個方法集合.當一個Observable發送出來值之后由Observer來決定如何的去使用它.而使用的方式就是通過回調函數.將Observable發送出來的值作為參數傳入其中.讓后在內部去使用.同時根據Observable發送出來的值不同.其調用的回調函數也不同.分別有next(下一步),error(報錯),complete(結束).下面是使用Observer的方法:
observable.subscribe(observer);
要使用觀察者,需要把它提供給 Observable 的 subscribe 方法
Subscription (訂閱)
什么是 Subscription?
Subscription
是表示可清理資源的對象,通常是 Observable 的執行。Subscription 有一個重要的方法,即 unsubscribe,它不需要任何參數,只是用來清理由 Subscription 占用的資源。在上一個版本的 RxJS 中,Subscription 叫做 "Disposable" (可清理對象)。
??Subscription(訂閱)是使用observable.subscribe()創建一個觀察者對象時.所返回的一個對象.它主要就是使用unsubscribe() 函數主動關閉Observer對Observable的監聽訂閱.其使用方法如下:
var observable = Rx.Observable.interval(1000);
var subscription = observable.subscribe(x => console.log(x));
// 稍后:
// 這會取消正在進行中的 Observable 執行
// Observable 執行是通過使用觀察者調用 subscribe 方法啟動的
subscription.unsubscribe();
Operators (操作符)
操作符是
Observable
類型上的方法,比如.map(...)、.filter(...)、.merge(...),
等等。當操作符被調用時,它們不會改變已經存在的Observable
實例。相反,它們返回一個新的Observable
,它的subscription
邏輯基于第一個Observable
。
操作符是函數,它基于當前的 Observable
創建一個新的 Observable
。這是一個無副作用的操作:前面的 Observable
保持不變。
就本質上而言Operators
就是一個純粹的函數.它可以接收一個 Observable
作為輸入.并在經過內部的一系列處理后返回一個新的Observable
作為輸出.流向下一個操作.
Subject (主體)
什么是 Subject? - RxJS Subject 是一種特殊類型的 Observable,它允許將值多播給多個觀察者,所以 Subject 是多播的,而普通的
Observables
是單播的(每個已訂閱的觀察者都擁有Observable
的獨立執行)。
`Subject` 像是 `Observalbe`,但是可以多播給多個觀察者。`Subject` 還像是` EventEmitters`,維護著多個監聽器的注冊表。
每一個Subject都同時是一個Observable
和Observer
.對于Subject
你可以使用subscribe
方法并指定一個觀察者.也可以調用next(v)、error(e)
和complete()
來處理接受道到值.示例如下:
var subject = new Rx.Subject();
subject.subscribe({
next: (v) => console.log('observerA: ' + v)
});
subject.subscribe({
next: (v) => console.log('observerB: ' + v)
});
subject.next(1);
subject.next(2);
在上面的示例中,我們為 Subject 添加了兩個觀察者,然后給 Subject 提供一些值
Schedulers (調度器)
什么是調度器? - 調度器控制著何時啟動 subscription 和何時發送通知。它由三部分組成:
- 調度器是一種數據結構。 它知道如何根據優先級或其他標準來存儲任務和將任務進行排序。
- 調度器是執行上下文。 它表示在何時何地執行任務(舉例來說,立即的,或另一種回調函數機制(比如 setTimeout 或 process.nextTick),或動畫幀)。
- 調度器有一個(虛擬的)時鐘。 調度器功能通過它的 getter 方法 now() 提供了“時間”的概念。在具體調度器上安排的任務將嚴格遵循該時鐘所表示的時間。
調度器可以讓你規定 Observable 在什么樣的執行上下文中發送通知給它的觀察者。