自学 Rx 快有一个周了, 它非常适合处理复杂的异步场景。结合自己所学,决定写系列教程。
我认为, Rx 中强大的地方在于两处
在 Rx 中,我们先预装好管道,通过管道流通数据 。这些管道的来源多种, create ,from, fromEvent, of .., 通过运算符将管道 拼接,合并,映射...形成最终的数据模型 。
对于管道来说,有两点非常重要
1. 管道是懒执行的,只有订阅器 observer subscribe了 数据管道,这个管道才会有数据流通 。
2. 整个节点组成一个完整的管道,订阅了后面的管道节点,也会同时订阅之前的管道节点 ,每个节点接受之前的值,并发出新值。
在很多教程中, Rx 往往以这个例子开始 :
```
const example = Rx.Observable.create ((observer) => {
const timer = setTimeout(() => {
observer.next(8);
})
observer.next(10);
return () => {
clearTimeout(timer);
}
})
const unsubscribe = example.subscribe((a) => {
console.log(a);
})
//结果当然是 10, 8.
```
这个例子发现了两种相似的设计模式
迭代器模式:类似于 JS 6 增加的迭代器 。
```
const iterator = [1, 2, 3][Symbol.iterator]();
while(true) {
const result = iterator.next();
if(result.done) return;
cnosole.log(result.value);
}
```
观察者模式: 事件模型是最常见的观察者模式, 定义生产者与消费者,生产者发出值,消费者收到消息,并执行相应行文 。 Observable 与其不同的是, Observable 是拉模型,懒执行,只有指定订阅者,生产者才会派发。 Rx 中的推模型实现Subject 就是采用观察者模式,不管有没有订阅者,都会推送数据 。
很多大牛介绍,在相对简单的情况下,大可不必使用 Observable ,Promise 足以应对。
类似于下面的模型
new Promise ((resolve, reject) = {})
.then()
.then()
.then() ...
这种模型非常大程度改善了 回调地狱, 也能处理大部分的异步场景,name 对于 Rx , 它有哪些地方不足呢 ?
1. Rx 抽象了数据的来源,主要是对事件和网络请求的抽象 。
2. Rx 可以多次发出数据, 而Promise 只能发出一次数据, 复用之前的管道。
3. Rx 可以是懒执行的,只有在订阅之后,才会发出值,也就是订阅 。 而Promise 在定义后理解执行 。
4. 注意到我们上面的例子,是可以cancle 取消订阅的。
```
return () => {
clearTimeout(timer);
}
})
const unsubscribe = example.subscribe((a) => {
console.log(a);
})
```
create 会返回一直函数,这个函数用于清理管道执行产生的垃圾,比如这里的定时器 。调用 unsubscribe 会取消订阅,并执行清理函数。
5. Promise 中数据变换只有通过then 链来进行,这点在fetch API 中体现最明显。 但是Rx 包含大量的运算符,简化了很多运算 。