从BehaviorSubject缓存管道的结果

时间:2018-04-26 16:32:02

标签: rxjs

使用rxjs,我有一个昂贵的计算来映射来自BehaviorSubject的结果:

const obs$ = sameBehaviorSubject.pipe(map(expensiveComputation));

然后在我的代码的其他多个部分中,我订阅了那个observable。每次订阅时,它都会重新运行expensiveComputation。我该如何防止这种情况?

2 个答案:

答案 0 :(得分:3)

您可以使用shareReplay:

const obs$ = sameBehaviorSubject.pipe(map(expensiveComputation), shareReplay(1));

现在,您可以多次订阅obs$而无需多次expensiveComputation次。

答案 1 :(得分:1)

更新:我已将此包含在我过去想要的(非常)小型rxjs工具库中。它是cache中提供的s-rxjs-utils函数。

@ siva636 给出了这个很好的答案:添加shareReplay(1)。它完全符合我的要求。

我添加此答案以显示另一种选择,其中一个小差异对我来说非常重要:添加publishReplay(1), refCount()。所以解决方案是:

const obs$ = someBehaviorSubject.pipe(
  map(expensiveComputation),
  publishReplay(1),
  refCount(),
);

当最后一个订阅者取消订阅obs$时会出现差异:shareReplay(1)会将其订阅保持为someBehaviorSubject,而此解决方案将取消订阅。我在Angular组件中创建这些可观察的元素随着时间的推移而变化,因此对我而言,当它们被破坏时,它们会完全清理干净。 shareReplay(1)泄露的订阅会随着时间的推移而不断累积,此解决方案不会。