Чтобы понять проблему, вы должны знать, что:
- Javascript однопоточный;
- Асинхронные события выполняются в цикле событий (например, Micro Task и Macro Task)
- Когда происходит асинхронное событие, оно добавляется в цикл событий;
- После добавления асинхронного события в цикл событий Javascript продолжает работу с синхронным кодом;
- После отсутствия синхронного кода запускается код событий из цикла Event.
Эта наблюдаемая будет синхронной, если вы не добавите delay(0)
:
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 factory и считает активные подписки с refCount
.