Разбираемся с Subject и его вариациями в Angular
Быстрый ответ
Subject
является мультикастером, способным передавать данные сразу нескольким подписчикам. Он идеален в случаях, когда наблюдателям важно присоединиться акрибно вовремя и получить данные в режиме реального времени.
BehaviorSubject
отличается тем, что всегда требует наличие начального значения и дарит новым подписчикам последнее обновление. Используйте его, когда вам необходимо сразу же передать данные о текущем состоянии.
ReplaySubject
обладает уникальной способностью повторять эмиссию предыдущих сообщений для всех, кто мог опоздать, давая им возможность увидеть события из прошлого.
Примеры кода для наглядности:
// Subject: передает данные только тем, кто уже в курсе.
let subject = new Subject();
subject.next(1);
subject.subscribe(console.log); // Пропускает единицу, ожидая двойку.
// BehaviorSubject: каждому новому подписчику дает в качестве презента последнее значение.
let behaviorSubject = new BehaviorSubject(1);
behaviorSubject.subscribe(console.log); // Сразу получает единицу.
behaviorSubject.next(2); // И теперь двойку.
// ReplaySubject: как запись лучших моментов для тех, кто опаздал.
let replaySubject = new ReplaySubject(2);
replaySubject.next(1);
replaySubject.next(2);
replaySubject.subscribe(console.log); // Видит и единицу, и двойку.
Советы по выбору:
- Выбирайте
Subject
, если важны данные, которые не остаются актуальными с течением времени. - Предпочтите
BehaviorSubject
, если вам нужен прямой доступ к последним актуальным данным. - Остановитесь на
ReplaySubject
, когда необходимо восстановить историю.
Подробный разбор с примерами применения
Управление состоянием и маршрутизация с использованием BehaviorSubject
BehaviorSubject – незаменимый инструмент в Angular для управления состоянием и использования в маршрутизационных стражах. Он незаменим, когда важно обладать последними данными о текущем состоянии и передавать последние изменения подписчикам.
// AppState, освещенный BehaviorSubject, всегда осведомлен о последних новостях
const appState = new BehaviorSubject(getInitialState());
appState.subscribe(state => {
// Все старые состояния отправляются в архив!
// Но вы всегда в курсе последних новостей. Как это круто!
});
appState.next(newState());
Использование ReplaySubject для учета изменений из прошлого
ReplaySubject – идеальный выбор для приложений, где ключевым является доступ как к текущим, так и к историческим данным. В частности, он отлично подходит для сервисов обмена сообщениями. Вы сами определяете, как много из прошлого хотите видеть, настроив размер буфера.
// Чат: ReplaySubject в действии!
const chatHistory = new ReplaySubject(100);
chatHistory.subscribe(messages => {
// Позволяет проследить за последними 100 сообщениями. Возвращаемся в прошлое!
});
chatHistory.next(newMessage());
Реагирование на события в реальном времени с помощью Subject
Лучшим выбором для работы с такими событиями, как нажатие кнопок и отправка форм, будет Subject. Не зацикливайтесь на прошлом, главное – то, что происходит прямо сейчас.
// Subject поможет легко ловить события отправки форм на лету.
const formSubmit = new Subject();
formSubmit.subscribe(action => {
// Старые новости не имеют значения, только свежие и актуальные данные.
});
formSubmit.next(submitEvent());
Визуализация
Subject 📸: Направлен исключительно на свежие новости. Про устаревшие забывает.
👀 👉 🖼️ | 🚫👀 🖼️🖼️
Subject подобен ленте социальных сетей: вы видите посты только после своего входа в систему.
BehaviorSubject 🔄📸: Приносит новые обновления и всегда сохраняет в памяти самое важное из увиденного.
👀 👉 🖼️ [🔝при необходимости]
BehaviorSubject – это словно популярная запись, всегда доступная для просмотра.
ReplaySubject 🔄🖼️: Переносит вас в прошлое, повторяя уже увиденные посты.
👀 👉 🖼️🖼️🖼️
ReplaySubject – ваши личные "Воспоминания" в социальных сетях, где можно просматривать старые публикации.
Основные различия и последствия их использования
Влияние на подписку и получение информации
Когда вы вступаете во взаимодействие с "социальной сетью" (подразумеваются типы Subject), это определяет, сколько истории вы сможете увидеть:
- С
Subject
те, кто приходит лишь позже, не видят ничего из того, что было до их прихода. BehaviorSubject
всегда покажет последнее сообщение, снабжая вас актуальным сведением о событиях.ReplaySubject
представит вам запись воспоминаний в зависимости от размера составленного вами буфера.
Размер буфера, потребление ресурсов и безопасность использования
Размер буфера ReplaySubject
может быть затратным с точки зрения потребления ресурсов, создавая риск "утечек памяти", если ваши действия непродуманны. Будьте осмотрительны при его настройке, особенно в рамках больших и сложных приложений.
Сценарий после завершения использования Subject
По завершению своей работы ReplaySubject
сохраняет лучшее из прошлого за счет кэшированных значений. Завершенный же BehaviorSubject
не так благожелателен и не предоставляет повторный доступ к прошлым событиям после окончания сеанса.
Рекомендации по использованию различных типов Subject
Подбор размера буфера под нужды проекта
Размер буфера следует выбирать в соответствии со сценарием использования вашего приложения. ReplaySubject с буфером 1
может выступать как альтернатива BehaviorSubject, или же вам может потребоваться более широкий взгляд на прошлое.
Предотвращение утечек памяти
Не забывайте об обязательности правильного завершения подписок. В Angular для этого предусмотрены хуки жизненного цикла ngOnDestroy
и операторы takeUntil
и takeWhile
.
Переключение между типами Subject
Вы можете легко преобразовать один тип Subject в другой. Например, если вам потребуется, чтобы Subject
запоминал последнее значение, простое превращение в BehaviorSubject
может стать решением.
Полезные материалы
- RxJS — официальная документация по RxJS Subjects.
- Subjects – Learn RxJS — детальное изучение BehaviorSubject, ReplaySubject и AsyncSubject.
- Angular University — глубокий анализ RxJS Subjects и BehaviorSubject в Angular.
- Academind – Экспертное обучение для достижения успеха! — подробное сравнение Subject, BehaviorSubject, ReplaySubject и AsyncSubject.
- Обсуждение на StackOverflow — основательное обсуждение BehaviorSubject против ReplaySubject.
- Все — это потоки – Роб Уормолд – YouTube — видеообзор основных понятий RxJS Subjects.
- RxJS Subjects для людей — простое и понятное применение RxJS Subjects в Angular.