首页 > 解决方案 > 为什么创建新订阅时扫描累加器值会重置,但使用 shareReplay(1) 时不会重置?

问题描述

我编写了以下代码,期望最后一次订阅将打印 ['emitted value 1', 'emitted value 2'],但只打印 ['emitted value 2']。这是有道理的,因为 BehaviorSubject 发出最后一个值,但为什么扫描累加器会重置为种子值?

我发现使用 shareReplay(1) 可以轻松解决此问题,但我不太明白为什么。在这两种情况下,使用 shareReplay(1) 与不使用它的扫描累加器发生了什么?

const subject = new BehaviorSubject(null);
const action$ = subject.asObservable();

const obs$ = action$.pipe(scan((acc, curr) => [...acc, curr], []));
// const obs$ = action$.pipe(scan((acc, curr) => [...acc, curr], []), shareReplay(1));

obs$.subscribe(res => console.log('first subs', res));

subject.next('emitted value 1');

subject.next('emitter value 2');

obs$.subscribe(res => console.log('second subs', res));

这是没有 shareReplay(1) 的控制台输出

并使用 shareReplay(1)

标签: javascriptrxjsbehaviorsubject

解决方案


当您订阅 a 时,BehaviorSubject您将收到最后发出的值。这就是为什么您只收到 :second subs ["emitter value 2"]在控制台中。

分享重播

来自文档

为什么要使用 shareReplay?当您不希望在多个订阅者之间执行的副作用或繁重的计算时,您通常希望使用 shareReplay。在您知道您将有迟到的订阅者需要访问先前发出的值的流的情况下,它也可能很有价值。这种在订阅时重播价值的能力是 share 和 shareReplay 的区别。

这意味着您将收到所有发出的值而无需任何计算,它是一种缓存。这在控制台中也可见,您只有一个包含第二个订阅的所有值的打印: second subs [null, "emitted value 1", "emitter value 2"]


推荐阅读