【问题标题】:Using delay(0) in combination with refCount()结合使用 delay(0) 和 refCount()
【发布时间】:2019-06-14 15:25:29
【问题描述】:

This article describes the refCount operator 并解释说,为了防止 obervable A 的取消订阅,我们必须将 delay(0) 添加到源 observable 中,以便从 "rxjs/Observable" 导入 { Observable };

    const source = Observable.defer(() => Observable.of(
    Math.floor(Math.random() * 100)
    )).delay(0);

0 总是够用吗?换句话说,传递零是否保证通知将延迟到所有m.subscribe() 语句都运行后,假设它们都在multicast 语句之后立即运行,如下所示:

const m = source.multicast(() => new Subject<number>()).refCount();
m.subscribe(observer("a"));
m.subscribe(observer("b"));

在上述情况下,我们只订阅观察者a 和b。如果我们在多播语句运行delay(0) 之后订阅了一百万个观察者,仍然保证他们都会在第一个源通知发生之前被订阅?

【问题讨论】:

  • 我遇到了delay(0) 的问题,它与setTimeout(..., 0) 的工作方式不同,原因(我认为..)是默认调度程序使用setInterval(..., 0),它有不同的行为,因为规范说 JS 中允许的最短间隔是 10 毫秒。其中,setTimeout(..., 0) 表示在下一个摘要中立即运行。所以它们并不完全相同,但我不确定这是否对你的问题有任何影响。仅供参考。

标签: javascript angular typescript rxjs


【解决方案1】:

要理解这个问题,你必须知道:

  • Javascript 是单线程的;
  • 异步事件在事件循环中运行(又名微任务和宏任务)
  • 当异步事件发生时,它被添加到事件循环中;
  • 在将异步事件添加到事件循环后,Javascript 继续使用同步代码;
  • 在没有剩余同步代码后,它从事件循环中运行事件代码。

如果您不添加 delay(0),此 Observable 将是同步的:

const source = Observable.defer(() => Observable.of(
Math.floor(Math.random() * 100)
)).delay(0);

当第一次订阅发生时(订阅是同步代码),Observable 立即发出,因为它也是同步的。但是如果你添加delay(0)(类似于setTimeout),Javascript 会等到所有同步代码(在这种情况下都是source.subscribe())都被执行。之后它将异步运行delay(0))。

这里:

const m = source.multicast(() => new Subject<number>()).refCount();
m.subscribe(observer("a"));
m.subscribe(observer("b"));

您有source Observable,它在其发射传递给delay(0) 后变为异步。此时,同步代码将继续(所有其他 source.subscribe() 调用),完成后,同步 delay(0) 将发出。

因此,即使在这种情况下执行数百万 source.subscribe() 调用也是安全的。

附言

multicast(() =&gt; new Subject&lt;number&gt;()).refCount() 与 share() 完全相同 - 它使用 Subject 工厂进行 multicast,并使用 refCount 计算活动订阅。

【讨论】:

  • 谢谢 - 很好的回答!!
猜你喜欢
  • 2019-05-16
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
  • 2011-07-26
相关资源
最近更新 更多