上一节我们对subject有了初步理解,今天我们继续学习subject
ReplaySubject
介绍这个ReplaySubject之前,我们说下一种使用场景
1、我们创建一个subject
2、在应用的某个地方,我们向subject推送值,但此时没有订阅
3、在某个时点,有第一个观察者开始订阅
4、我们期望观察者能发出之前主体推送的值(可能是全部值或者时其中一个)
5、实际上啥都没发生,因为主体不能存储记忆值
在这种情况下,ReplaySubject能够帮助我们实现以上情景需要的功能。这种情况就是,Subject 将记录发出的值,并将订阅时发出的所有值推送给观察者。
这里有一个问题?
ReplaySubject 是重放所有值还是只重放最近的一个?
默认情况下,主题将重播所有发出的值,但我们可以提供一个名为 bufferSize 的参数。这个参数定义了 ReplaySubject 应该在它的内存中保存的发射数量:
图表说明
代码举例
onst subject$ = new ReplaySubject(1);
subject$.next(1);
subject$.next(2);
subject$.next(3);
subject$.subscribe(console.log);
// Output
// 3
还有第二个参数可以传递给 ReplaySubject 以定义旧值应该在内存中存储多长时间。
const subject$ = new ReplaySubject(100, 250);
setTimeout(() => subject$.next(1), 50);
setTimeout(() => subject$.next(2), 100);
setTimeout(() => subject$.next(3), 150);
setTimeout(() => subject$.next(4), 200);
setTimeout(() => subject$.next(5), 250);
setTimeout(() => {
subject$.subscribe(v => console.log('SUBCRIPTION A', v));
}, 200);
setTimeout(() => {
subject$.subscribe(v => console.log('SUBCRIPTION B', v));
}, 400);
日志信息:
SUBCRIPTION A 1
SUBCRIPTION A 2
SUBCRIPTION A 3
SUBCRIPTION A 4
SUBCRIPTION A 5
SUBCRIPTION B 4
SUBCRIPTION B 5
结果分析
订阅 A 能够重播所有项目,但订阅 B 只能重播项目 4 和 5,因为它们是在指定窗口时间内发出的唯一值。
BehaviorSubject
BehaviorSubject 可能是 Subject 中最著名的子类。这种Subject代表“当前值”。也是我们只用最多的。
与 ReplaySubject 类似,它也会在观察者订阅它时重播当前值。
为了使用 BehaviorSubject,我们需要在实例化时提供一个强制性的初始值。
图表说明
代码举例
const subject$ = new BehaviorSubject(0); // 0 is the initial value
subject$.next(1);
setTimeout(() => {
subject$.subscribe(console.log);
}, 200);
// 1
结果分析
每当发出新值时,BehaviorSubject 都会将该值存储在属性值中,该值也可以公开访问。