Observable(可观察对象)
Observable(可观察对象)是基于推送(Push)运行时执行(lazy)的多值集合。
拉取(Pull)和推送(Push)
拉取和推送是数据生产者和数据消费者之间通信的两种不同机制。
- 拉取:在拉取系统中,总是由消费者决定何时从生产者那里获得数据。生产者对数据传递给消费者的时间毫无感知(被动的生产者,主动的消费者)
- 推送:在推送系统中生产者决定何时向消费者传递数据,消费者对何时收到数据毫无感知(被动的消费者)
js中的Promise和Observable
- 现代JavaScript中Promise是典型的推送系统。作为数据生产者的Promise通过resolve()向数据消费者――回调函数传递数据:与函数不同,Promise决定向回调函数推送值的时间
- RxJS在JavaScript中引入了Observable(可观察对象)这个新的推送系统。Observable是多数据值的生产者,向Observer(被动的消费者)推送数据
Observable与函数、promsise
- 函数是当调用才同步计算,并最终只返回一个值的
- promise是会或者不会返回一个值
- Observable是当调用才同步或者异步地计算,并可能产生0到无穷多个值的
Observable是函数概念的拓展
- Observable就像一个没有参数的函数,并不断生成一些值供我们使用,因此它也像是一个事件发射机(EventEmitters)
- 在Observable中subscribe就像call一个函数,你订阅它,它才会被'启动'。同一个Observable对于不同的subscribe,是不会共享结果的(通常情况下这样子的,但可以通过调用api来共享)
Observable四大核心
创建
- Rx.Observable.create是Observable构造函数的别名,接受一个参数:subscribe函数
- 除了使用create创建Observable,我们通常还使用创建操作符, 如of,from,interval,等来创建Observable
订阅
- observable.subscribe和Observable.create(function subscribe(observer) {…})中的subscribe不是同一个对象,但在工程中可以在概念上视两者为等价物
- 调用subscribe的观察者并不会共享同一个Observable
- 订阅机制与处理事件的addEventListener/removeEventListenerAPI完全不同。通过observable.subscribe,观察者并不需要在Observable中进行注册,Observable也不需要维护订阅者的列表
- 订阅后便进入了Observable的执行阶段,在执行阶段值和事件将会被传递给观察者供其消费
执行
- 只有在被订阅之后Observable才会执行,执行的逻辑在Observable.create(function subscribe(observer){…})中描述,执行后将会在特定时间段内,同步或者异步地成产多个数据值
- Observable在执行过程中,可以推送三种类型的值:
- “Next” 通知: 实际产生的数据,包括数字、字符串、对象等
- “Error” 通知:一个JavaScript错误或者异常
- “Complete” 通知:一个不带有值的事件
- 在Observable的执行过程中,0个或者多个“Next”通知会被推送
- 在错误或者完成通知被推送后,Observable不会再推送任何其他通知
终止
- Observable的执行可能是无限的,作为观察者需要主动中断执行:我们需要特定的API去终止执行过程
- 因为特定的观察者都有特定的执行过程,一旦观察者获得想要的数据后就需要终止执行过程以免带来计算时对内存资源的浪费
- 在observable.subscribe被调用时,观察者会与其执行作用域绑定,同时返回一个Subscription类型的对象,通过调用subscription.unsubscribe()你可以终止执行过程
angular 有个类叫Observable。 从名字可以看出它提供一个观察者模式的类似功能。
也就是说,当我们把一个函数的返回值用Observable类包装后, 调用函数的使用方就可以订阅该函数,然后在得到通知后处理后续的事情, 也就是异步的调用过程而不是同步等待。
import { Observable } from 'rxjs/rx';
import { of } from 'rxjs/observable/of';
getHeroes(): Observable<Hero[]> {
this.messageService.add('HeroService: fetched heroes');
return of(HEROES);
}
上面的函数用Observable封装, of强转后就是一个异步的函数, 这样外部在函数完成后调用后续的处理,比如refresh
this.heroService.getHeroes().subscribe(heroes => this.refreshTree(heroes));
参考:
https://stackoverflow.com/questions/37364973/promise-vs-observable
https://angular.cn/tutorial/toh-pt4#observable-data