pull和push体系
在上篇文章中我们了解了Observer pattern和Iterator pattern,我们可以发现Observer是生产者(Producer)主动推送数据(push ),而Iterator是消费者(Consumer)主动要求数据(pull).
那么什么是pull和push呢?
拉和推是数据生产者和数据的消费者两种不同的交流协议(方式).
| Producer | Customer | |
|---|---|---|
| pull | Passive(被动的一方):被请求的 时候产生数据 | Active(起主导的一方):决定何时请求 数据 |
| push | Active:按自己的节奏生产数据 | Passive:对接收的数据做出反应(处 理接收到的数据) |
- 在"拉"体系中,数据的消费者决定何时从数据生产者那里获取数据,而生产者自身并不会意识到什么时候数据将会被发送给消费者。
每一个 JS函数都是一个“拉”体系,函数是数据的生产者,调用函数的代码通过“拉 出”一个单一的返回值来消费该数据(return语句)。
- 在推体系中,数据的生产者决定何时发送数据给消费者,消费者不会在接收数据之前意识到它将要接收这个数据。
Promise是当今JS中最常见的Push推体系,一个Promise(数据的生产者)发送一个resolved value(成功状态的值)来注册一个回调(数据消费者),但是不同于函数的地方的是:Promise决定着何时数据才被推送至这个回调函数。
RxJS引入了Observable(可观察对象),一个全新的"推体系"。一个可观察对象是一个产生多值的生产者,并"推送给Observer(观察者)。
以下是pull和push体系的几种代表。
| Single单值 | Multiple多值 | |
|---|---|---|
| pull | Function | Iterator |
| push | Promise | Observable |
RxJS 中的观察者模式和迭代器模式
前面提到RxJS 是基于观察者模式和迭代器模式以函数式编程思维来实现的, RxJS 中含有两个基本概念:Observable 与 Observer。Observable 作为可观察对象(被观察者),是一个以惰性的方式推送多值的流集合;而 Observer 则作为观察者,根据 Observable进行处理。
Observable 与 Observer 之间的订阅发布关系(观察者模式) 如下:
-
订阅:
Observer通过Observable提供的subscribe()方法订阅Observable。 -
发布:
Observable通过回调next方法向Observer发布事件。
Observer(观察者)是Observable(可观察对象)所发送数据的消费者,Observer简单而言是一组 回调函数 , 分别对应一种被可观察对象发送的通知的类型:next, error和 complete。
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
那么迭代器模式在 RxJS 中如何体现呢?
- next:
Observer提供一个next方法来接收Observable流,是一种push形式,而Iterator是通过调用iterator.next()来获取数据,是一种pull形式。 - complete:当不再有新的值发出时,将触发
observer的complete方法;而Iterator中则是当next的返回结果中done为true时,表示complete。 - error:当在处理事件中出现异常报错时,
Observer提供error方法来接收错误进行统一处理;Iterator则需要进行try catch包裹来处理可能出现的错误。