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
等等。