juejin.cn/post/684490… ----转载我们创建了一个 ReplaySubject 并指定其只存储最近两次广播的值;
订阅 subject 并称其为订阅者A;
subject 连续广播三次,同时订阅者A 也会跟着连续打印三次;
这一步就轮到 ReplaySubject 展现魔力了。我们再次订阅 subject 并称其为订阅者B,因为之前我们指定 subject 存储最近两次广播的值,所以 subject 会将上两个值“重播”给订阅者B。我们可以看到订阅者B 随即打印了这两个值;
subject 最后一次广播,两个订阅者收到值并打印。
我们创建了一个 ReplaySubject,指定其存储最近两次广播的值,但只保留 100ms;
订阅 subject 并称其为订阅者A;
我们让这个 subject 每 200ms 广播一次。订阅者A 每次都会收到值并打印;
我们设置在程序执行一秒后再次订阅 subject,并称其为订阅者B。这意味着在它开始订阅之前,subject 就已经广播过五次了。由于我们在创建 subject 时就设置了数据的过期时间为 100ms,而广播间隔为 200ms,所以订阅者B 在开始订阅后只会收到前五次广播中最后一次的值。
多播的基本含义是:一个 Observable execution 可以在多个订阅者之间共享。
Subject 的作用是实现 Observable 的多播。由于其 Observable execution 是在多个订阅者之间共享的,所以它可以确保每个订阅者接收到的数据绝对相等。不仅使用 Subject 可以实现多播,RxJS 还提供了一些 Subject 的变体以应对不同场景,那就是:BehaviorSubject、ReplaySubject 以及 AsyncSubject。
1,BehaviorSubject 的特性就是它会存储“当前”的值。这意味着你始终可以直接拿到 BehaviorSubject 最后一次发出的值。
2,ReplaySubject 是可以给新订阅者发送“旧”数据的。另外,ReplaySubject 还有一个额外的特性就是它可以记录一部分的 observable execution,从而存储一些旧的数据用来“重播”给新来的订阅者。
当创建 ReplaySubject 时,你可以指定存储的数据量以及数据的过期时间。也就是说,你可以实现:给新来的订阅者“重播”订阅前一秒内的最后五个已广播的值。示例代码如下:
import * as Rx from "rxjs";
const subject = new Rx.ReplaySubject(2);
// 订阅者 A
subject.subscribe((data) => {
console.log('Subscriber A:', data);
});
subject.next(Math.random())
subject.next(Math.random())
subject.next(Math.random())
// 订阅者 B
subject.subscribe((data) => {
console.log('Subscriber B:', data);
});
subject.next(Math.random());
// Subscriber A: 0.3541746356538569
// Subscriber A: 0.12137498878080955
// Subscriber A: 0.531935186034298
// Subscriber B: 0.12137498878080955
// Subscriber B: 0.531935186034298
// Subscriber A: 0.6664809293975393
// Subscriber B: 0.6664809293975393 之前提到了你还可以设置 ReplaySubject 的数据过期时间。让我们来看看下面这个例子:
import * as Rx from "rxjs";
const subject = new Rx.ReplaySubject(2, 100);
// 订阅者A
subject.subscribe((data) => {
console.log('Subscriber A:', data);
});
setInterval(() => subject.next(Math.random()), 200);
// 订阅者B
setTimeout(() => {
subject.subscribe((data) => {
console.log('Subscriber B:', data);
});
}, 1000)
// Subscriber A: 0.44524184251927656
// Subscriber A: 0.5802631630066313
// Subscriber A: 0.9792165506699135
// Subscriber A: 0.3239616040117268
// Subscriber A: 0.6845077617520203
// Subscriber B: 0.6845077617520203
// Subscriber A: 0.41269171141525707
// Subscriber B: 0.41269171141525707
// Subscriber A: 0.8211466186035139
// Subscriber B: 0.8211466186035139 3,BehaviorSubject 和 ReplaySubject 都可以用来存储一些数据,而 AsyncSubject 就不一样了。AsyncSubject 只会在 Observable execution 完成后,将其最终值发给订阅者。
import * as Rx from "rxjs";
const subject = new Rx.AsyncSubject();
// 订阅者A
subject.subscribe((data) => {
console.log('Subscriber A:', data);
});
subject.next(Math.random())
subject.next(Math.random())
subject.next(Math.random())
// 订阅者B
subject.subscribe((data) => {
console.log('Subscriber B:', data);
});
subject.next(Math.random());
subject.complete();
// Subscriber A: 0.4447275989704571
// Subscriber B: 0.4447275989704571