RxJS 是一個使用可觀察量(observable)隊列解決異步編程和基於事件編程的js庫。
他提供了一個核心的類型Observable
,和若干附屬類型(Observer
、Schedulers
、Subject
)以及一組的操做符(map
,filter
,reduce
,every
等等),能夠像操做集合同樣處理異步事件流。react
Think of RxJS as Lodash for events.編程
爲了較好的管理事件隊列,響應式編程組合了觀察者模式和迭代器模式,而且提供了操做集合的函數式編程方法。數組
RxJS提供了幾個管理異步事件的核心概念:併發
Observable
: 可觀察量,表明了一個由將來獲取到的值或事件組成的集合。異步
Observer
:觀察者,是一個集合,由監聽Observable推送消息的一個或多個回調函數組成。函數式編程
Subscription
:訂閱過程,表明了Observable的執行過程,一般用來取消或者中斷Observable的執行過程。異步編程
Operators
: 操做符是一些純函數,用來採用函數式編程風格處理集合,好比:map
,filter
,concat
,flatMap
等等。函數
Subject
: Subject至關於事件觸發器(EventEmitter),是向多個Observer廣播事件或推送值的惟一方法。spa
Schedulers
: 調度者集中了派發器(dispatcher)控制併發,容許咱們在使用相似setTimeout()
,requestAnimationFrame
或其餘方法時,協調計算。
一般你會像下面這樣註冊事件偵聽器:
var button = document.querySelector('button'); button.addEventListener('click', () => console.log('Clicked!'));
使用RxJS,你能夠建立一個observable,處理相同的邏輯:
var button = document.querySelector('button'); Rx.Observable.fromEvent(button, 'click') .subscribe(() => console.log('Clicked!'));
採用純函數生產數據,使RxJS的能力很強,也能夠減小代碼出錯的概率。
一般,一個不純函數中的部分代碼可能會擾亂狀態,相似:
var count = 0; var button = document.querySelector('button'); button.addEventListener('click', () => console.log(`Clicked ${++count} times`));
使用RxJS,你能夠將狀態隔離起來:
var button = document.querySelector('button'); Rx.Observable.fromEvent(button, 'click') .scan(count => count + 1, 0) .subscribe(count => console.log(`Clicked ${count} times`));
例子中的scan
操做符相似於數組的reduce()
方法。他將一個值傳遞給回調函數,以後的返回值則會做爲一個輸入被傳遞給下一個時間點上的回調函數。
爲了控制Observable實例中事件流,RxJS提供了各類各樣的操做符。
如下的例子展現了使用純js,實現至少間隔1秒發出一次點擊事件的代碼:
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(); } });
使用RxJS,能夠這樣:
var button = document.querySelector('button'); Rx.Observable.fromEvent(button, 'click') .throttleTime(1000) .scan(count => count + 1, 0) .subscribe(count => console.log(`Clicked ${count} times`));
還有不少控制流的操做符,好比:filter
,delay
,debounceTime
,take
,takeUntil
,distinct
,distinctUntilChanged
等等。
你能夠改變Observable流中的值。
如下的例子,使用純js實現了獲取每次click事件時鼠標x座標的值,並進行了計算:
var count = 0; var rate = 1000; var lastClick = Date.now() - rate; var button = document.querySelector('button'); button.addEventListener('click', (event) => { if (Date.now() - lastClick >= rate) { count += event.clientX; console.log(count) lastClick = Date.now(); } });
使用RxJS,你能夠這樣:
var button = document.querySelector('button'); Rx.Observable.fromEvent(button, 'click') .throttleTime(1000) .map(event => event.clientX) .scan((count, clientX) => count + clientX, 0) .subscribe(count => console.log(count));
其餘用來加工和生產值的操做符有:pluck
,pairwise
,sample
等等。