Ответ
Stream в Dart — это последовательность асинхронных событий. Это фундаментальная абстракция для реактивного программирования во Flutter, используемая для обработки данных, поступающих со временем: пользовательские события, ответы от сервера, показания датчиков, обновления состояния.
Базовый пример создания и подписки:
// Создание простого Stream с использованием async*
Stream<int> countDown(int from) async* {
for (int i = from; i >= 0; i--) {
await Future.delayed(const Duration(seconds: 1));
yield i; // Каждую секунду выдаём новое значение
}
}
void main() {
final stream = countDown(5);
// Подписка на поток
final subscription = stream.listen((value) {
print('Осталось: $value сек');
}, onDone: () {
print('Отсчёт завершён!');
});
// subscription.cancel(); // Для отмены подписки
}
Ключевые операции с Stream (трансформации):
stream
.where((value) => value.isEven) // Фильтрация
.map((value) => value * 2) // Преобразование
.take(3) // Ограничение количества событий
.listen(print);
Использование во Flutter с StreamBuilder:
StreamBuilder — это виджет, который автоматически перестраивает UI в ответ на новые данные из Stream.
class DataDisplayWidget extends StatelessWidget {
final Stream<String> dataStream;
const DataDisplayWidget({super.key, required this.dataStream});
@override
Widget build(BuildContext context) {
return StreamBuilder<String>(
stream: dataStream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Ошибка: ${snapshot.error}');
}
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const CircularProgressIndicator();
default:
return Text('Полученные данные: ${snapshot.data}');
}
},
);
}
}
Важные концепции:
- Холодный (Cold) Stream: Начинает генерировать события при появлении первого слушателя (как в примере с
async*). - Горячий (Hot) Stream: Генерирует события независимо от наличия слушателей (например,
StreamController.broadcast()). - Управление подпиской: Крайне важно отменять подписки (
subscription.cancel()) в методеdispose()StatefulWidgetили использовать пакеты вродеrxdart, которые предоставляют автоматическое управление жизненным циклом.
Streams лежат в основе многих популярных менеджеров состояний Flutter, таких как BLoC (где StreamController используется для приёма событий и эмиссии состояний).