Разбираемся с Subject и его вариациями в Angular

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Subject является мультикастером, способным передавать данные сразу нескольким подписчикам. Он идеален в случаях, когда наблюдателям важно присоединиться акрибно вовремя и получить данные в режиме реального времени.

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

ReplaySubject обладает уникальной способностью повторять эмиссию предыдущих сообщений для всех, кто мог опоздать, давая им возможность увидеть события из прошлого.

Примеры кода для наглядности:

JS
Скопировать код
// 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, когда необходимо восстановить историю.
Кинга Идем в IT: пошаговый план для смены профессии

Подробный разбор с примерами применения

Управление состоянием и маршрутизация с использованием BehaviorSubject

BehaviorSubject – незаменимый инструмент в Angular для управления состоянием и использования в маршрутизационных стражах. Он незаменим, когда важно обладать последними данными о текущем состоянии и передавать последние изменения подписчикам.

JS
Скопировать код
// AppState, освещенный BehaviorSubject, всегда осведомлен о последних новостях
const appState = new BehaviorSubject(getInitialState());

appState.subscribe(state => {
  // Все старые состояния отправляются в архив!
  // Но вы всегда в курсе последних новостей. Как это круто!
});

appState.next(newState());

ReplaySubject – идеальный выбор для приложений, где ключевым является доступ как к текущим, так и к историческим данным. В частности, он отлично подходит для сервисов обмена сообщениями. Вы сами определяете, как много из прошлого хотите видеть, настроив размер буфера.

JS
Скопировать код
// Чат: ReplaySubject в действии!
const chatHistory = new ReplaySubject(100);

chatHistory.subscribe(messages => {
  // Позволяет проследить за последними 100 сообщениями. Возвращаемся в прошлое!
});

chatHistory.next(newMessage());

Реагирование на события в реальном времени с помощью Subject

Лучшим выбором для работы с такими событиями, как нажатие кнопок и отправка форм, будет Subject. Не зацикливайтесь на прошлом, главное – то, что происходит прямо сейчас.

JS
Скопировать код
// Subject поможет легко ловить события отправки форм на лету.
const formSubmit = new Subject();

formSubmit.subscribe(action => {
  // Старые новости не имеют значения, только свежие и актуальные данные.
});

formSubmit.next(submitEvent());

Визуализация

Markdown
Скопировать код
Subject 📸: Направлен исключительно на свежие новости. Про устаревшие забывает.
           👀 👉 🖼️ | 🚫👀 🖼️🖼️

Subject подобен ленте социальных сетей: вы видите посты только после своего входа в систему.

Markdown
Скопировать код
BehaviorSubject 🔄📸: Приносит новые обновления и всегда сохраняет в памяти самое важное из увиденного.
                     👀 👉 🖼️ [🔝при необходимости]

BehaviorSubject – это словно популярная запись, всегда доступная для просмотра.

Markdown
Скопировать код
ReplaySubject 🔄🖼️: Переносит вас в прошлое, повторяя уже увиденные посты.
                  👀 👉 🖼️🖼️🖼️

ReplaySubject – ваши личные "Воспоминания" в социальных сетях, где можно просматривать старые публикации.

Основные различия и последствия их использования

Влияние на подписку и получение информации

Когда вы вступаете во взаимодействие с "социальной сетью" (подразумеваются типы Subject), это определяет, сколько истории вы сможете увидеть:

  • С Subject те, кто приходит лишь позже, не видят ничего из того, что было до их прихода.
  • BehaviorSubject всегда покажет последнее сообщение, снабжая вас актуальным сведением о событиях.
  • ReplaySubject представит вам запись воспоминаний в зависимости от размера составленного вами буфера.

Размер буфера, потребление ресурсов и безопасность использования

Размер буфера ReplaySubject может быть затратным с точки зрения потребления ресурсов, создавая риск "утечек памяти", если ваши действия непродуманны. Будьте осмотрительны при его настройке, особенно в рамках больших и сложных приложений.

Сценарий после завершения использования Subject

По завершению своей работы ReplaySubject сохраняет лучшее из прошлого за счет кэшированных значений. Завершенный же BehaviorSubject не так благожелателен и не предоставляет повторный доступ к прошлым событиям после окончания сеанса.

Рекомендации по использованию различных типов Subject

Подбор размера буфера под нужды проекта

Размер буфера следует выбирать в соответствии со сценарием использования вашего приложения. ReplaySubject с буфером 1 может выступать как альтернатива BehaviorSubject, или же вам может потребоваться более широкий взгляд на прошлое.

Предотвращение утечек памяти

Не забывайте об обязательности правильного завершения подписок. В Angular для этого предусмотрены хуки жизненного цикла ngOnDestroy и операторы takeUntil и takeWhile.

Переключение между типами Subject

Вы можете легко преобразовать один тип Subject в другой. Например, если вам потребуется, чтобы Subject запоминал последнее значение, простое превращение в BehaviorSubject может стать решением.

Полезные материалы

  1. RxJSофициальная документация по RxJS Subjects.
  2. Subjects – Learn RxJS — детальное изучение BehaviorSubject, ReplaySubject и AsyncSubject.
  3. Angular University — глубокий анализ RxJS Subjects и BehaviorSubject в Angular.
  4. Academind – Экспертное обучение для достижения успеха! — подробное сравнение Subject, BehaviorSubject, ReplaySubject и AsyncSubject.
  5. Обсуждение на StackOverflow — основательное обсуждение BehaviorSubject против ReplaySubject.
  6. Все — это потоки – Роб Уормолд – YouTube — видеообзор основных понятий RxJS Subjects.
  7. RxJS Subjects для людей — простое и понятное применение RxJS Subjects в Angular.