Что такое Subject в Dart (rxdart)?

«Что такое Subject в Dart (rxdart)?» — вопрос из категории Реактивное программирование, который задают на 36% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Subject — это специальный контроллер потока из библиотеки rxdart, который одновременно является и Stream (на него можно подписаться), и Sink (в него можно добавлять события). Это «горячий» поток, который начинает эмитировать данные сразу и может иметь несколько подписчиков.

Основные типы Subject в rxdart:

  1. PublishSubject: Передает только события, произошедшие после подписки. Не хранит предыдущие значения.
  2. BehaviorSubject: Кеширует и передает новым подписчикам последнее отправленное значение.
  3. ReplaySubject: Кеширует и передает новым подписчикам заданное количество последних значений.

Пример использования BehaviorSubject для управления состоянием:

import 'package:rxdart/rxdart.dart';

class AuthService {
  // Создаем Subject, который хранит последнее значение (начальное — false)
  final _isLoggedIn = BehaviorSubject<bool>.seeded(false);
  // Предоставляем поток для подписки в UI
  Stream<bool> get isLoggedInStream => _isLoggedIn.stream;

  void login() {
    // ... логика входа
    _isLoggedIn.add(true); // Уведомляем всех подписчиков
  }

  void logout() {
    // ... логика выхода
    _isLoggedIn.add(false);
  }

  void dispose() {
    _isLoggedIn.close(); // Важно закрыть при завершении
  }
}
// В UI:
StreamBuilder<bool>(
  stream: authService.isLoggedInStream,
  builder: (context, snapshot) {
    return snapshot.data == true ? HomePage() : LoginPage();
  },
)

Зачем использовать? Subject идеально подходит для ручного управления событиями в реактивном стиле, например, для стримов событий из UI (клики, текстовый ввод) или как основа для простых State Management решений.