Как создать Stream в Dart?

«Как создать Stream в Dart?» — вопрос из категории Реактивное программирование, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Dart есть несколько основных способов создания Stream:

1. Использование StreamController Это наиболее гибкий способ, когда нужно генерировать события программно.

final StreamController<int> controller = StreamController<int>();
final Stream<int> myStream = controller.stream;

// Добавление данных в поток
controller.sink.add(1);
controller.sink.add(2);
controller.sink.addError(Exception('Something went wrong'));

// Обязательно закрываем контроллер, когда он больше не нужен
await controller.close();

*2. Асинхронный генератор (`async`)** Идеально подходит для создания потоков на основе асинхронной логики или последовательностей.

Stream<int> countDown(int from) async* {
  for (int i = from; i >= 0; i--) {
    yield i; // Каждый yield отправляет значение в поток
    await Future.delayed(const Duration(seconds: 1));
  }
}
// Использование
final countdownStream = countDown(5);

3. Преобразование существующих данных

// Из Future
Stream<int> streamFromFuture = Stream.fromFuture(Future.delayed(
  Duration(seconds: 2),
  () => 42,
));

// Из Iterable (например, List)
Stream<int> streamFromList = Stream.fromIterable([1, 2, 3, 4, 5]);

// Периодический поток
Stream<int> periodicStream = Stream.periodic(
  const Duration(seconds: 1),
  (count) => count,
).take(10); // Ограничиваем 10 значениями

Ключевой момент: Поток (Stream) — это источник асинхронных событий: данных (data), ошибок (error) или сигнала о завершении (done). Для прослушивания используется метод listen().