This article describes the refCount operator并解释说,为了防止取消订阅 obervable A,我们必须将 delay(0)
添加到源 observable 中,这样 import { Observable } from "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"));
在上面的例子中,我们只订阅了观察者a
和b
。如果我们在运行 delay(0)
的多播语句之后订阅了一百万个观察者,仍然保证在第一个源通知发生之前他们都将被订阅吗?
最佳答案
要理解这个问题,您必须知道:
- 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(() => new Subject<number>()).refCount()
与 share()
完全相同- 它使用 Subject 工厂进行 multicast 并使用 refCount
计算活跃订阅数.
关于javascript - 将 delay(0) 与 refCount() 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56601176/