likes
comments
collection
share

聊一下rxjs中的单播、多播以及share的使用

作者站长头像
站长
· 阅读数 3

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:

聊一下rxjs中的单播、多播以及share的使用聊一下rxjs中的单播、多播以及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

聊一下rxjs中的单播、多播以及share的使用聊一下rxjs中的单播、多播以及share的使用

上面的例子里 share 和 subject 要一起用,才不会重复执行tap。

因为 Subject 在经过的操作符处理后,返回的是普通的 Observable 了。如果未使用share操作符,那么中间经过的操作符处理路径也是相互独立的,也就会各自执行tap。

其实多注意到“操作符处理后,返回的是啥”的细节后就不会有误解了。