RxJS 是一个库,它通过使用 observable 序列来编写异步和基于事件的程序。它提供了一个核心类型Observable,附属类型(Observer、 Schedulers、 Subjects) 和受 [Array#extras] 启发的操作符 (map、filter、reduce、every, 等等),这些数组操作符可以把异步事件作为集合来处理。
可以把 RxJS 当做是用来处理事件的Lodash。
ReactiveX 结合了观察者模式、迭代器模式和使用集合的函数式编程,以满足以一种理想方式来管理事件序列所需要的一切。
在 RxJS 中用来解决异步事件管理的的基本概念是:
map
、filter
、concat
、flatMap
等这样的操作符来处理集合。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类似。它需要一个暴露给回调函数当参数的初始值。每次回调函数运行后的返回值会作为下次回调函数运行时的参数。
RxJS 提供了一整套操作符来帮助你控制事件如何流经 observables 。
下面的代码展示的是如何控制一秒钟内最多点击一次,先来看使用普通的 JavaScript:
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等等。
对于流经 observables 的值,你可以对其进行转换。
下面的代码展示的是如何累加每次点击的鼠标 x 坐标,先来看使用普通的 JavaScript:
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等等。