何时应该使用 `publishReplay` 和 `shareReplay`?

45

我已经知道了

  • publish 共享一个订阅,同时返回一个ConnectableObservable(所以我们必须Connect()

  • Share()publish().refcount()

Replay后缀非常明显,它会返回最后一次发出的值。

让我们以Angular HTTP请求为例,其中包含现有和未来的订阅:

<p>{{ (person | async)?.id   }}</p> //present markup

<p *ngIf=”show”>{{ (person | async)?.userId }}</p> <!-- future markup -->

如果我不想有多个http请求,我可以使用:

publishReplay().Connect()

但我也可以使用:shareReplay(),但我确信有一种方法比另一种更正确。

问题:

在什么情况下应该使用publishReplay而不是shareReplay? 在当前和未来的HTTP请求方面有什么区别?

NB 为什么没有关于shareReplay的文档?

3个回答

76

shareReplay()基本上就是publishReplay().refCount()

绝对不是。

shareReplaypublishReplay(+在其上调用connect)都会使其后面的observable成为热的。

但它们之间非常重要的区别是:

  • shareReplay: 不会停止发出值,直到它完成,无论订阅者是否已经取消订阅。
  • publishReplay: 如果与refCount一起使用,将在最后一个订阅者取消订阅后停止。

我认为这是至关重要的信息。


4
非常关键!同时请注意,一个新的功能(配置选项)即将推出,将进一步复杂化/简化事情(具体涉及 shareReplay 的取消订阅行为):https://github.com/ReactiveX/rxjs/issues/3336 - 已在 https://github.com/ReactiveX/rxjs/pull/4059 中修复。 - Simon_Weaver
5
这个特性已经在6.4.0版本中发布了 :) - Flash
2
有关6.4.0中新配置对象的文章:https://medium.com/@cartant/rxjs-whats-changed-with-sharereplay-65c098843e95 - Simon_Weaver
1
长期以来,我一直在探讨它们之间的确切区别,但最终我找到了这篇文章:https://itnext.io/the-magic-of-rxjs-sharing-operators-and-their-differences-3a03d699d255。它从“publish”/“share”开始(这就是我恍然大悟的地方),然后扩展到后面的“publishReplay”+“shareReplay”。 - ntziolis

20

publishReplay允许您控制订阅何时开始。 shareReplay将在第一次订阅时自动启动。

通常,如果要在模板(html文件)中使用observable,请使用shareReplay。 优点是您不必担心取消订阅等问题。


2
如果是这样,那我不明白为什么引用计数是0,但它仍然会发出一个值供未来的订阅使用,是因为回放吗?http://jsbin.com/nirisugudi/edit?html,js,console - Royi Namir
2
另外,关于您的评论和问题中的模板,|async 不也自动取消订阅吗? - Royi Namir
@RoyiNamir 是的,那是正确的。所以这是你想要的吗?我不明白这与你的问题有什么关系。 - martin
3
refCount()控制ConnectableObservable何时连接到其源Observable,它与shareReplay内的缓冲区无关。换句话说,即使publishReplay取消订阅其父级,缓冲区仍然存在,并且发送给每个新观察者,而不管publishReplay是否订阅其源。 - martin
所以,如果 http(假设)的设计不完整,那么从 0 增加 refcount 会触发另一个请求吗? - Royi Namir
显示剩余11条评论

5

shareReplay() 基本上等同于 publishReplay().refCount()

这里有一篇详细解释它们之间关系的优秀文章:"Angular Async Pipes  - Beware the share"

编辑:

正确的说法是:

shareReplay() 类似于 publishReplay().refCount()

请查看@DevRok的回答,了解它们为什么不完全相同的更多信息。


1
请查看Devrok的答案。 - Simon_Weaver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接