Что такое Subject, BehaviorSubject, и ReplaySubject?angular-41

В RxJS Subject — это особый тип Observable, который позволяет multicast (многоадресная рассылка) значения многим подписчикам. Рассмотрим основные виды Subject и их особенности.

1. Subject

Базовый Subject — это "горячий" Observable, который:

  • Не хранит значение по умолчанию
  • Отправляет значения только текущим подписчикам
  • Не имеет "памяти" о предыдущих значениях
const subject = new Subject<number>();

subject.subscribe(v => console.log(`Subscriber A: ${v}`));
subject.next(1); // Subscriber A: 1

subject.subscribe(v => console.log(`Subscriber B: ${v}`));
subject.next(2);
// Subscriber A: 2
// Subscriber B: 2

Когда использовать:

  • Когда нужен простой механизм событий
  • Когда не требуется хранить предыдущие значения
  • Для ручного управления потоком данных

2. BehaviorSubject

BehaviorSubject хранит текущее значение и отправляет его новым подписчикам:

const behaviorSubject = new BehaviorSubject<number>(0); // 0 - начальное значение

behaviorSubject.subscribe(v => console.log(`Subscriber A: ${v}`));
// Сразу получает текущее значение: Subscriber A: 0

behaviorSubject.next(1); // Subscriber A: 1

behaviorSubject.subscribe(v => console.log(`Subscriber B: ${v}`));
// Получает последнее значение: Subscriber B: 1

Особенности:

  • Требует начального значения
  • Всегда имеет "текущее значение" (можно получить через .value)
  • Новые подписчики сразу получают последнее значение

Когда использовать:

  • Для хранения и распространения состояния (например, в сервисах)
  • Когда важно, чтобы новые подписчики получали актуальное значение

3. ReplaySubject

ReplaySubject может "воспроизводить" несколько предыдущих значений новым подписчикам:

const replaySubject = new ReplaySubject<number>(2); // хранит 2 последних значения

replaySubject.next(1);
replaySubject.next(2);
replaySubject.next(3);

replaySubject.subscribe(v => console.log(`Subscriber A: ${v}`));
// Получает 2 последних значения:
// Subscriber A: 2
// Subscriber A: 3

Можно также указать время "жизни" значений (в миллисекундах):

const replaySubject = new ReplaySubject<number>(100, 500);
// хранит 100 последних значений или те, что были отправлены за последние 500мс

Особенности:

  • Может хранить несколько предыдущих значений
  • Гибкая настройка (количество значений и/или время хранения)
  • Полезен для кэширования данных

Когда использовать:

  • Когда новые подписчики должны получить историю изменений
  • Для реализации шаблона "Event Sourcing"
  • Для отладки потоков данных

Сравнительная таблица

Характеристика Subject BehaviorSubject ReplaySubject
Начальное значение Нет Да Нет
Хранит текущее значение Нет Да Да (настраиваемое количество)
Новые подписчики получают Ничего Текущее значение Последние N значений
Использование События Состояние История событий

Практические примеры использования

  1. Subject — для пользовательских событий (клики, ввод)
  2. BehaviorSubject — для хранения текущего пользователя, темы приложения
  3. ReplaySubject — для чатов, истории изменений, аналитики

Резюмируем

  • Subject — простой механизм событий без памяти
  • BehaviorSubject — хранит и передает текущее значение (аналог "переменной")
  • ReplaySubject — хранит и передает историю значений (аналог "ленты событий")