Использование delay (0) в сочетании с refCount () - PullRequest
2 голосов
/ 14 июня 2019

В этой статье описывается оператор refCount и объясняется, что для предотвращения отказа от подписки на обозримый объект A мы должны добавить delay(0) к наблюдаемому источнику, так чтобы th импортировал {Observable} из "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), мы по-прежнему гарантируем, что все они будут подписаны до того, как произойдет уведомление о первом источнике?

1 Ответ

1 голос
/ 14 июня 2019

Чтобы понять проблему, вы должны знать, что:

  • 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...