Rxjs简介中文翻译
综述
简介
RxJS是一个通过使用可见队列构成异步编程和基于事件编程的库。它提供了一个核心的类型,可见的卫星类型(Observer, Schedulers, Subjects),也提供了由数组的扩展操作激发的操作者类型,把异步的事件作为集合进行操作。
因此,可以把RxJS看做一个事件的Lodash。
ReactiveX 结合了观察者模式、迭代器模式和集合函数式编程来管理事件队列。
&RxJS解决异步事件管理的基本概念是:
- Observable:代表即将发生的事件或改变的值的可调用集合。
- Observer:知道如何监听可见量分发的值的回调函数的集合。
- Subscription:可见量的执行过程,用于取消执行过程。
- Operators:允许对集合进行函数式编程风格操作的纯函数,例如map,filter,concat,flatMap等。
- Subject:等价于一个事件发射器,是对多个观察者广播值或事件的唯一方式。
-Schedulers:控制并发的中央分派器,允许我们操作事件何时发生,例如 setTimeout or 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!'));
Purity
使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`));
这个sacn操作者就会像数组的reduce操作一样,它产生一个传递给回调函数的值,该值为累积结果,并且在下一次调用该回调函数时作为参数提供。
Flow
RxJS有一个全程的operators来帮你控制事件如何在你的observables中流动。
下面这个例子说明如何控制一秒最多点击一次,使用原生JS的如下:
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`));
其它流控制的operators有filter,delay,debounceTime,take,takeUntil,distinct,distinctUntilChanged等
Values
你可以在你的observables中改变传递的值。
下面显示如何用原生的JS为每一个点击时间添加当前鼠标的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) {
console.log(++count + event.clientX)
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));
其它产生值的operators有pluck, pairwise, sample 等等。
Observable
Observables是多值操作的惰性Push集合,它形成了下述表格
Table | Single | Multiple |
---|---|---|
Pull | Function | Iterator |
Push | Promise | Observable |
例子:下面是一个observable在subscribed的时候同步push1,2,3的值的例子,4这个值是在subscribe调用一秒之后才会被传递,才完成所有的push操作。代码如下:
var observable=Rx.Observable.create(function (observer) {
observer.next(1);
observer.next(2);
observer.next(3);
setTimeout(() => {
observer.next(4);
observer.complete();
}, 1000);
});
为了调用这个observable来观察这些值,我们需要订阅它:
var observable=Rx.Observable.create(function (observer) {
observer.next(1);
observer.next(2);
observer.next(3);
setTimeout(() => {
observer.next(4);
observer.complete();
}, 1000);
});
console.log('just before subscribe');
observable.subscribe({
next: x => console.log('got value ' + x),
error: err => console.error('something wrong occurred: ' + err),
complete: () => console.log('done'),
});
console.log('just after subscribe');
执行完的结果如下:
just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 4
done
Pull versus Push
Pull和Push是数据的生产者和消费者之间沟通的不同协议。
Pull是什么?在Pull的系统里,消费者决定什么时候从生产者那里接收数据。生产者本身是不会感知数据是什么时候传递给消费者的。
每一个JavaScript的函数都是一个Pull系统。函数是数据的生产者,调用这个函数的代码通过pulling out获得这个函数的执行结果的返回值。
ES2015引入了generator functions and iterators (function*),另一类Pull 系统。调用iterator.next()的代码是消费者,从iterator(生产者)那里pulling out多个值。
Table | Producer | Consumer |
---|---|---|
Pull | Passive:produces data when requested. | Active:decides when data is requested . |
Push | Active:produces data at its own pace. | Passive:reacts to received data. |
什么是Push?在push系统里,生产者决定什么时候把数据发送给消费者。消费者感知不到它什么时候会收到数据。
Promise 是JavaScript中最常见的Push系统。一个Promise(生产者)传递一个