将delay(0)与refCount()结合使用

时间:2019-06-14 15:25:29

标签: javascript angular typescript rxjs

This article describes the refCount operator并解释说,为了防止取消对可观察到的A的订阅,我们必须在可观察到的源中添加delay(0),以便从“ rxjs / 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"));

在上述情况下,我们仅订阅观察者ab。如果我们在多播语句将运行delay(0)之后订阅了一百万个观察者,还保证他们在第一个源通知发生之前都将被订阅吗?

1 个答案:

答案 0 :(得分: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()调用也很安全。

p.s。

multicast(() => new Subject<number>()).refCount()share()完全相同-它使用 Subject 工厂进行多播,并使用{{1 }}。