Cold & Hot Observable
Hot Observable跟Cold Observable的差别,其实就是资料源(Data Source)在Observable内部建立还是外部建立。
在RxJS中很常会看到Cold Observable跟Hot Observable这两个名词,其实他们是在区分不同行为的Observable,所谓的Cold Observable就是指每次订阅都是独立的执行,而Hot Observable则是共用的订阅。
Cold Observable
Cold Observable 代表Observable 的每个订阅都是独立的,他们不会互相影响,如下
const source = Rx.Observable.interval(1000).take(5);
source.subscribe(value => console.log('sub1: ' + value))
setTimeout(() => {
source.subscribe(value => console.log('sub2: ' + value))
}, 3500);
// sub1: 0
// sub1: 1
// sub1: 2
// sub1: 3
// sub2: 0
// sub1: 4
// sub2: 1
// sub2: 2
// sub2: 3
// sub2: 4
从上面的程式码可以看出来每次订阅source
都是独立运行的,这种每次订阅都是独立执行的Observable就称为Cold Observable。
如果从Observable内部来看,代表资料源(Data Source)是在Observable内部建立的的,大概会长像下面
const source = Rx.Observable.create(function(observer) {
// 订阅时,才建立新的资料源
const someDataSource = getSomeDataSource();
someDataSource.addEventListener('message', (data) => {
observer.next(data)
})
})
因为每次订阅都建立一个新的资料源,就会使资料从头开始传送。
Hot Observable
Hot Observable 代表Observable 的每个订阅是共用的,所谓的共用订阅就是指一个Observable 在多次订阅时,不会每次都从新开始发送元素,例如
var source = Rx.Observable.interval(1000)
.take(5)
.share(); // 共用
source.subscribe(value => console.log('sub1: ' + value))
setTimeout(() => {
source.subscribe(value => console.log('sub2: ' + value))
}, 3500);
// sub1: 0
// sub1: 1
// sub1: 2
// sub1: 3
// sub2: 3
// sub1: 4
// sub2: 4
从上面的程式码可以看出,当我们对source第二次做订阅时,接收到的元素是接续第一个订阅往下发送的,而不是从新(0)开始,这种
共用订阅的Observable就称为Hot Observable。
如果从Observable内部来看,就是资料源是在Observable外部建立的,程式码大概就会像下面这样
// 只有一个资料源,每次订阅都是用同一个
const someDataSource = getSomeDataSource();
const source = Rx.Observable.create(function(observer) {
someDataSource.addEventListener('message', (data) => {
observer.next(data)
})
});
Cold 与Hot
一般的情况下Observable 都是Cold 的,这样不同的订阅才不会有Side Effect 互相影响。但在需要多次订阅的情境下,我们就很有可能需要Hot Observable,而让RxJS 提供了很多让Cold Observable 变成Hot Observable 的方法,这个部分可以参考以下文章:
30 天精通RxJS(22): Subject 基本观念
30 天精通RxJS(24): Observable operators - multicast, refCount, publish, share
小结
Hot Observable 跟Cold Observable 的差异就是多次订阅时,是否共用订阅或是独立执行。而这一切的差异就是来自于资料源是在Observable 内部建立还是外部建立。