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 subscribegot value 1got value 2got value 3just after subscribegot value 4done复制代码
那么迭代器模式在 RxJS
中如何体现呢?
- next:
Observer
提供一个next
方法来接收Observable
流,是一种push
形式,而Iterator
是通过调用iterator.next()
来获取数据,是一种pull
形式。 - complete:当不再有新的值发出时,将触发
observer
的complete方法;而Iterator
中则是当next的返回结果中done
为true
时,表示complete
。 - error:当在处理事件中出现异常报错时,
Observer
提供error
方法来接收错误进行统一处理;Iterator
则需要进行try catch
包裹来处理可能出现的错误。