【问题标题】:Angular 2 + RxJS: async pipe with .share() operatorAngular 2 + RxJS:带有 .share() 运算符的异步管道
【发布时间】:2016-09-20 19:19:18
【问题描述】:

在使用 .share() 运算符的 observable 上使用 async 管道时(由于后端计算成本很高),我偶然发现了这种行为:

data$ = (new Observable(observer => {
    let counter=0;
    observer.next(counter)

    window.setInterval(() => {
      observer.next(counter);
      counter++;
    }, 2000);
  }))
  .share();

模板:

{{ (data$|async) !== null }}
{{ (data$|async) !== null }}

初始值的输出为:

true false

以下输出(超过 2 秒后)是:

true true

这也是我期望的第一个值的行为。 如果我省略.share(),第一个值的输出是"true true",正如我所料。我想上面的行为是由于模板中的第一个表达式触发了 observable 执行,一旦第二个async 管道订阅了 observable,数据就已经消失了。这个解释正确吗?我该如何避免这种行为?

【问题讨论】:

  • 既然应该有一个值,那就是observer.next(...); observer.complete()
  • 具有单个值的示例仅用于演示,在我的应用中,observable 具有多个值
  • 请提供反映您情况的代码。
  • 我用示例代码编辑了我的问题: observable 的第一个值会触发奇怪的行为,而后面的不会。您是否知道一种方法可以使两个异步管道的第一个值都可用?
  • 我想是的。在 RxJS4 中使用了shareReplay(1)(顾名思义,它共享最后 1 个值的重放)。对于 A2+RxJS5 可以直接使用对应的,看答案。

标签: angular rxjs observable


【解决方案1】:

根据the reference

异步管道订阅 Observable 或 Promise 并返回它发出的最新值。

在 RxJS 4 中,shareReplay 用于实现所需的行为。

在 RxJS 5 中,shareReplay 的直接对应物是 publishReplay,后跟 refCountsee the explanationthe discussion)。

应该是这样的

data$ = (new Observable(observer => { ... }))
.publishReplay(1)
.refCount();

【讨论】:

  • 但是为什么它显示 true 然后 false ? (时间=0)
  • 因为在时间 0 data$ 包含一个值 (0),并且在使用第一个 (data$|async) 订阅后,它已“用尽”。由于 data$ 中没有第二个值,并且 (data$|async) 表达式应该同步解析为某个值,因此它解析为 null(这就是 async 管道的工作原理)。
  • 等一下,在 time=0 时,有多少订阅者存在?1 还是 2? (我问它是因为共享看到引用计数。)。你能在 refcount POV 中解释一下吗?
  • {{ (data$|async) !== null }} {{ (data$|async) !== null }} 创建 2 个订阅,对于共享的 observable 有 2 个引用计数。
  • RxJS 6 怎么样?还有(或再次?)shareReplay()。这篇博文说它也是 RxJS 5.4 (blog.angularindepth.com/…) 的一部分。还是这与版本 4 的 shareReplay() 不同?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
  • 2020-08-30
  • 1970-01-01
相关资源
最近更新 更多