javascript - 为什么创建新订阅时扫描累加器值会重置,但使用 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));
解决方案
当您订阅 a 时,BehaviorSubject
您将收到最后发出的值。这就是为什么您只收到 :second subs ["emitter value 2"]
在控制台中。
分享重播
来自文档:
为什么要使用 shareReplay?当您不希望在多个订阅者之间执行的副作用或繁重的计算时,您通常希望使用 shareReplay。在您知道您将有迟到的订阅者需要访问先前发出的值的流的情况下,它也可能很有价值。这种在订阅时重播价值的能力是 share 和 shareReplay 的区别。
这意味着您将收到所有发出的值而无需任何计算,它是一种缓存。这在控制台中也可见,您只有一个包含第二个订阅的所有值的打印:
second subs [null, "emitted value 1", "emitter value 2"]
推荐阅读
- python - 从 .csv 文件到单个单元格的熊猫数据框
- c# - 如何在同一行代码中拒绝非整数和负数?C#
- azure - Azure 云服务重定向到 https 协议
- javascript - 如何在javascript中将6英尺4英寸转换为米
- php - 如何将文件从内存存储到 Laravel5 的存储中?
- django - 如何使用分页在模板中打印存储过程的结果?
- c++ - C ++按数字比较两个数字
- r - 在 Shiny App 中,我希望根据数据表中的搜索结果更新绘图。
- amazon-web-services - SageMaker RCF 数据
- javascript - 在转换流/打字稿后保留类型检查