聊一下rxjs中的单播、多播以及share的使用
share 的 使用
官方说share的作用是“把单播变成多播”,等会再聊单播与多播,直接看看 share 的使用:
share 让多个 observer 共享相同的流(Observable)。
作用就是第一个 observer 订阅时触发了流的产生,然后第二个 observer 订阅就直接连接这个已存在的流,而不是重新连接。这样两个 observer 收到的就是相同的事件/值。
举个例子:
import { interval } from 'rxjs';
import { share } from 'rxjs/operators';
// interval返回了一个每秒产生一个数字的 Observable。
const observable = interval(1000).pipe(share()); // 加share, 可以通过share操作符转成多播。
// const observable = interval(1000); // 不加share, 就是单播
// 第一个 observer 订阅 Observable
observable.subscribe((value) => {
console.log('观察者 A:', value);
});
// 延迟一段时间后,第二个 observer 订阅 Observable
setTimeout(() => {
observable.subscribe((value) => {
console.log('观察者 B:', value);
});
}, 3000);
结果如下,第一个图加了share,第二个图删除了share:
单播与多播
结合上面的使用 share 的例子就容易理解单播和多播了:
单播是指每个 observer 之间的流是相互独立的。
多播是指多个 observer 之间的流是共享的。
详细点说,
单播是指每个 observer 从 observable 收到的事件/值 是相互独立的,中间经过的操作符处理路径也是相互独立的。
多播是指每个 observer 从 observable 收到的事件/值 是一致的,中间经过的操作符处理路径也是一致的。
在 rxjs 中,普通的 Observable 是默认是单播的,Observable 可以通过 share 操作符转成多播。而Subject是多播的。
误解:share 和 subject 不需要再一起用
subject 本身是多播的,share 又是“把单播变成多播”,所以误以为 share 和 subject 不需要再一起用。
先看看下方用/不用share的例子:
import { Subject } from 'rxjs';
import { share, tap, map } from 'rxjs/operators';
const mySubject = new Subject<number>();
const observable = mySubject.pipe(
map((value) => value * 2),
tap((val) => console.log('=== tap:',val)),
share() // 删除此行,看不用share的效果
); // mySubject.pipe(...) 执行后注意返回的是 Observable
observable.subscribe((val) => console.log('val1', val));
observable.subscribe((val) => console.log('val2', val));
mySubject.next(1);
mySubject.next(2);
结果:第一个图不用share,第一二图用了share
上面的例子里 share 和 subject 要一起用,才不会重复执行tap。
因为 Subject 在经过的操作符处理后,返回的是普通的 Observable 了。如果未使用share操作符,那么中间经过的操作符处理路径也是相互独立的,也就会各自执行tap。
其实多注意到“操作符处理后,返回的是啥”的细节后就不会有误解了。
转载自:https://juejin.cn/post/7352162941313810483