Description
chapter2-RxJS入门
1
/*
* 导入方式
*
* - import语法导入
* import Rx from 'rxjs';
*
* - commonJS风格的require函数
* const Rx = require('rxjs');
*
*/
上面的两种写法是一样的效果,但上面的导入写法会将整个RxJS库都导入进来,会让打包文件较大。
解决这个问题可以使用深链(deep link)的方式,只导入用上的功能。比如要使用Observable类:
import Observable from 'rxjs/Observable';
或者使用CommonJS风格的require函数:
const Observable = require('rxjs/Observable').Observable;
RxJS的架构设计决定了Tree-Shaking无法对其起作用。RxJS的大部分功能都是围绕Observable类而创建的,而且这些功能都体现为Observable这个类的一个函数,有的是类函数,有的是成员函数,这些函数都是要‘挂’到Observable这个类上去。换句话说,这些函数不管我们的应用代码用还是不用,在RxJS内部都已经被Observable类‘引用’了,被引用知乎,Tree-Shaking就不会觉得这些函数是“枯枝”,也就会在打包文件中保留下来。
2
RxJS中的数据流就是Observable对象,每个Observable对象代表的就是在一段时间内发生的一系列事件。Observable实现了下面来两种设计模式:
- 观察者模式
- 迭代器模式
Observable可以用下面这种公式表示:Observable = Publisher + Iterator
import {Observable} from 'rxjs/Observable';
const onSubscribe = observer => {
observer.next(1);
observer.next(2);
const timer = setTimeout(()=>{
clearTimeout(timer);
observer.next(3);
observer.complete();
},1000)
}
const source$ = new Observable(onSubscribe);
const theObserver = {
next: item => console.log(item),
error: (err) => console.log(err),
complete: () => console.log("No More Data")
}
source$.subscribe(theObserver);
/*
*
* 1、函数onSubscribe会被用作Observable构造函数的参数,这个函数参数完全决定了Observable对象的行为。onSubscribe函数接受一个名为observer的参数,函数体内,调用参数observer的next函数,把数据推给observer。
* 2、调用Observable构造函数产生一个名为source$的数据流对象
* 3、创造观察者theObserver
* 4、通过subscribe(订阅)函数将theObserver和source$关联起来
*
*/
创建Observable对象就是创建了一个“发布者”,Observable的subscribe函数被调用之后对应的onSubscribe函数就会被调用,参数就是观察者对象,上例中观察者就是theObserver。onSubscribe函数中可以任意操作观察者对象。这个过程就等于在这个Observable对象上挂上了号,以后当这个Observable对象产生数据时,观察者就会获得通知。
Observer对象的complete函数和error函数何时被调用,完全看Observable对象的行为,和数据一样,完结信号和错误信号也是由Observable推给Observer的
3
为了让代码更简洁,没有必要创造一个Observer对象,subscribe也可以直接接收函数作为参数,第一个参数如果是函数类型,就被认为是next,第二个参数如果是函数类型,就被认为是error,第三个参数被认为是complete。
source$.subscribe(
item => console.log(item),
err => console.log(err),
() => console.log("No More Data")
);
如果不关心不关心异常的处理,但是关心Observable的终止事件,那依然要传递第二个参数来占位置,可以传递null,表示不处理异常事件。
上面的例子中onSubscribe函数并没有返回任何结果,其实onSubscribe函数可以返回一个对象,对象上可以有一个unsubscribe函数。代表的就是和subscribe“订阅”相反的动作,也就是退订。
const onSubscribe = observer => {
observer.next(1);
observer.next(2);
const timer = setTimeout(()=>{
clearTimeout(timer);
observer.next(3);
observer.complete();
},1000)
return {
unsubscribe: ()=>{}
}
}
unsubscribe函数调用之后,作为Observer不再接受到被推送的数据。但是作为Observable的source$在没有调用complete或者errror的情况下不会终结,只不过它再也不会调用next函数了。这是RxJS中很重要的一点:Observable产生的事件,只有Observer通过subscribe订阅之后才会收到,在unsubscribe之后就不会再收到
4
Hot Observable: 只接受从订阅那一刻开始Observable产生的数据
Cold Observable: 在subscribe之前Observable产生的数据也要获取
每一个Cold Observable概念上都可以理解成对每一次subscribe都产生一个“生产者”,然后这个生产者产生的数据通过next函数传递给订阅的Observer。上面的Observable对象source$是Cold Observable,因为每次通过subscribe函数添加一个Observer,这个Observable对象都会直接调用参数的next函数传递固定的数据。可以认为固定的数据就是一个简单的“生产者”。
而对于Hot Observable,概念上是有一个独立于Observable对象的“生产者”,这个“生产者”的创建和subscribe调用没有关系,subscribe调用只是让Observer连接上“生产者”而已。
Cold Observable和Hot Observable的概念代码
// Cold Observable
const cold$ = new Observable(observer => {
const producer = new Producer();
// 然后让observer去接受producer产生的数据
})
// Hot Observable
const producer = new Producer();
const hot$ = new Observable(observer => {
// 然后让observer去接受producer产生的数据
})
在Hot Observable中,Observable明显并不产生数据,只是数据的搬运工。