В недавнем прошлом я очень ценил RxJS за его способность управлять асинхронными операциями. Это действительно сдвиг в парадигме программирования того, как вы смотрите на асинхронный код. Если он будет последовательно хорошо принят во всем приложении, вы можете увидеть значительное улучшение в управлении асинхронным кодом. В этом посте я хочу поговорить об особом принципе Observables. Этот пост не имел бы большого смысла, если бы вы не знакомы с RxJS.

Отказ от подписки или отмена.

Одной из ключевых особенностей Observables является его способность отменять базовую операцию источника. Фактически, документация ReactiveX объясняет основную цель Subscription как это.

Подписка: представляет выполнение Observable, в первую очередь полезно для отмены выполнения.

Однако, если вы достаточно долго используете RxJS, это не кажется естественным для Observables. Шаблон, кажется, почти диктует, что Subscriptions являются просто «зрителями» для источника, а не чем-то, что контролирует источник. В основном это происходит из-за различных типов наблюдаемых объектов, которые мы используем, и нашей неспособности всегда знать, какой тип является наблюдаемым и что на самом деле происходит, когда вы делаете unsubscribe из Subscription.

Наблюдаемая температура.

Одно из ключевых понятий, которое вносит непоследовательность в то, как вы смотрите на наблюдаемый объект, - это температура. Observable может быть горячим или холодным, а иногда даже теплым. Я не собираюсь обсуждать наблюдаемую температуру в этом посте, хотя это ключ к пониманию остальной части этого поста. В основном потому, что это то, что обсуждается довольно подробно, и этот пост от Shouldtram отлично справляется с этим.

Прочитав вышеуказанный пост, вы также узнаете, что есть операторы, которые можно использовать для изменения температуры Observable. В частности, такие операторы, как publish, refCount, share и defer.

Горячие наблюдаемые

Как вы, возможно, уже поняли, повлиять на базовую операцию горячего наблюдаемого невозможно. Это связано с тем, что источник не контролирует лежащую в основе операцию. Итак, когда вы subscribe, вы, по сути, только начинаете слушать. Точно так же, когда вы unsubscribe вы прекращаете слушать. Ниже приводится классический пример горячей наблюдаемой.

let source = fromEvent( element, ‘mousemove’ );

В следующем примере мы создаем горячую наблюдаемую с помощью оператора create. Это может показаться излишним, но сделано исключительно для того, чтобы объяснить привязанность наблюдаемого объекта к основной операции.

Как видите, тикер запускается каждые 100 мс при запуске кода. Наблюдаемый объект, возвращаемый getTicks, передает подписчику каждый тик. Observable всегда сообщает каждому наблюдателю текущий тик, независимо от того, когда наблюдатель подписался. Отказавшись от подписки, вы по существу перестаете слушать, но тикер продолжает работать.

Холодные наблюдаемые

С другой стороны, холодные наблюдаемые могут повлиять на базовую операцию, специфичную для наблюдателя. В холодных наблюдаемых объектах наблюдатель запускает базовую операцию для этого наблюдателя с subscribe. Точно так же наблюдатель заканчивает базовую операцию для этого наблюдателя с unsubscribe. Большинство операторов создания создают холодное наблюдаемое.

let source = range( 1, 10 );

Вышеупомянутая наблюдаемая выдает значения от 1 до 10, когда наблюдатель подписывается. Для каждого другого наблюдателя, который подписывается, значения отправляются снова. Давайте рассмотрим это подробнее на примере тикера, в котором для создания холодного наблюдаемого используется только оператор create.

В этом случае тикер не запускается, пока наблюдатель не подпишется на getTicks observable. Каждый раз, когда наблюдатель подписывается на наблюдаемое, создается новый тикер, который исходит из 0. Когда наблюдатель отписывается, базовый тикер, специфичный для этого наблюдателя, останавливается. Это идентично

getTicks(){
   return interval(100);
}

Пример тикера показывает, что когда вы unsubscribe из холодного наблюдаемого источника, вы существенно влияете на работу источника, специфичную для этого наблюдателя / подписки.

Теплые наблюдаемые

Теплые наблюдаемые - это наблюдаемые, температура которых изменяется от горячей к холодной. Сообщение Хотятрама объясняет некоторые случаи теплых наблюдаемых. Есть много разных случаев теплых наблюдаемых. Давайте возьмем случай холодного наблюдаемого, которое становится горячим при подписке и снова становится холодным, когда все наблюдатели отписываются от него. Этого можно добиться с помощью следующих операторов.

let source = interval(100).pipe( publish(), refCount());

В этом случае interval производит холодное наблюдаемое, но publish (вместе с connect operator) делает его горячим наблюдаемым. refCount делает его теплым - сначала холодным, но становится горячим при первой подписке. Давайте воспользуемся примером тикера с оператором create, чтобы создать теплую наблюдаемую, которая ведет себя аналогичным образом.

В этом конкретном случае наблюдатели полностью контролируют базовую операцию наблюдаемого. Создав первую подписку, мы можем запустить тикер, а отказавшись от всех подписок, мы можем остановить тикер.

Заключение

Observables действительно дают возможность подписчику управлять основной операцией, но только в некоторых случаях. Это не очень хорошо, особенно если подписчик не знает, к какому типу относится наблюдаемый объект и что он обозначает. Так что это то, чего нужно остерегаться и решать в каждом конкретном случае. При неправильном использовании этот конкретный аспект наблюдаемых может привести к проблемам, которые трудно отследить. Тем не менее, RxJS и Observables стали отличной платформой для управления асинхронным кодом и вывода его на новый уровень.