在RxJS 中 Observables 分为两种:Cold Observables 和 Hot Observables。
Cold Observables
Cold Observables 只有被 observers 订阅的时候,才会开始产生值。是单播的,有多少个订阅就会生成多少个订阅实例,每个订阅都是从第一个产生的值开始接收值,所以每个订阅接收到的值都是一样的。
Cold Observables 示例:
import { Observable } from 'rxjs';
let observable = new Observable((observer: any) => {
let count = 0;
let intervalId = setInterval(() => {
count++;
if (count < 3) {
observer.next(count);
} else {
observer.complete();
clearInterval(intervalId);
}
}, 1000);
});
observable.subscribe(
data => { console.log(`1st subscribe: ${data}`) },
(err) => { console.log(`1st subscribe err: ${err}`) },
() => { console.log(`1st subscribe complete`) });
setTimeout(() => {
observable.subscribe(
data => { console.log(`2nd subscribe: ${data}`) },
(err) => { console.log(`2nd subscribe err: ${err}`) },
() => { console.log(`2nd subscribe complete`) });
}, 2000);
setTimeout(() => {
observable.subscribe(
data => { console.log(`3rd subscribe: ${data}`) },
(err) => { console.log(`3rd subscribe err: ${err}`) },
() => { console.log(`3rd subscribe complete`) });
}, 5000);
运行结果:
可以看到最后一个订阅在 observer.complete(); 完成之后才添加的,但是它仍然接收到了全部的数据值。
Hot Observables
Hot Observables 不管有没有被订阅都会产生值。是多播的,多个订阅共享同一个实例,是从订阅开始接受到值,每个订阅接收到的值是不同的,取决于它们是从什么时候开始订阅。
在RxJS中,可以使用 publish 操作符,ConnectableObservable,以及 connect() 方法创建 Hot Observables :
import { Observable } from 'rxjs';
import { publish } from 'rxjs/operators';
let observable = new Observable((observer: any) => {
let count = 0;
let intervalId = setInterval(() => {
count++;
if (count < 3) {
observer.next(count);
} else {
observer.complete();
clearInterval(intervalId);
}
}, 1000);
}).pipe(publish()) as ConnectableObservable<any>;
observable.connect();
observable.subscribe(
data => { console.log(`1st subscribe: ${data}`) },
(err) => { console.log(`1st subscribe err: ${err}`) },
() => { console.log(`1st subscribe complete`) });
setTimeout(() => {
observable.subscribe(
data => { console.log(`2nd subscribe: ${data}`) },
(err) => { console.log(`2nd subscribe err: ${err}`) },
() => { console.log(`2nd subscribe complete`) });
}, 2000);
setTimeout(() => {
observable.subscribe(
data => { console.log(`3rd subscribe: ${data}`) },
(err) => { console.log(`3rd subscribe err: ${err}`) },
() => { console.log(`3rd subscribe complete`) });
}, 5000);
运行结果:
可以看到对于 Hot Observables, 在某个值被发出之后再添加的订阅,不能接收到该值及其之前发出的值。但是能收到完成通知。
操作符及方法说明:
- publish: 这个操作符把一般的 Observable(Cold Observables )转换成ConnectableObservable。
- ConnectableObservable: 是 Observable 的变种,属于 Hot Observable,会一直等待,直到 connnect 方法被调用才会开始把值发送给那些订阅它的观察者。
- connect:ConnectableObservable 并不会主动发送值,通过调用 connect 方法,可以启动ConnectableObservable 发送值。当调用 connect 方法时,不管有没有被订阅,都会发送值。