Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Для чего нужны Stream?
Stream — это один из самых мощных и фундаментальных инструментов в Dart и Flutter для асинхронной обработки данных. Это абстракция, которая позволяет работать с последовательностями событий, поступающих во времени.
Основное назначение Stream
Stream предоставляет способ обработки асинхронных последовательностей данных. Вместо того чтобы получить результат сразу, вы подписываетесь на Stream и получаете значения по мере их появления. Это особенно полезно когда:
- Данные поступают асинхронно — с сервера, из файлов, с датчиков
- Нужно реагировать на изменения — обновление состояния в реальном времени
- Обработка множественных событий — клики пользователя, сообщения, уведомления
- Работа с веб-сокетами — live-данные, chat-приложения
Основные типы Stream
Single-subscription Stream — может иметь только одного слушателя:
Stream<int> numbersStream = Stream<int>.periodic(
Duration(seconds: 1),
(count) => count,
).take(5);
var subscription = numbersStream.listen((value) {
print("Значение: $value");
});
Broadcast Stream — может иметь множество слушателей одновременно:
Stream<int> broadcastStream = numbersStream.asBroadcastStream();
var subscription1 = broadcastStream.listen((value) {
print("Слушатель 1: $value");
});
var subscription2 = broadcastStream.listen((value) {
print("Слушатель 2: $value");
});
Практическое применение во Flutter
1. Работа с BLoC паттерном
Stream используются в BLoC (Business Logic Component) для управления состоянием:
class CounterBloc {
final _counterController = StreamController<int>();
Stream<int> get counterStream => _counterController.stream;
void increment() {
_counter++;
_counterController.sink.add(_counter);
}
void dispose() {
_counterController.close();
}
}
2. StreamBuilder для обновления UI
StreamBuilder<int>(
stream: bloc.counterStream,
initialData: 0,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text("Ошибка: ${snapshot.error}");
}
return Text("Значение: ${snapshot.data}");
},
)
3. Работа с API данными
Stream<List<User>> fetchUsersStream() async* {
final response = await http.get(Uri.parse(apiUrl));
if (response.statusCode == 200) {
List<User> users = parseUsers(response.body);
yield users;
} else {
throw Exception("Ошибка загрузки");
}
}
Трансформация Stream
Stream можно преобразовывать с помощью операторов:
stream
.map((value) => value * 2) // преобразование
.where((value) => value > 5) // фильтрация
.distinct() // удаление дубликатов
.debounce(Duration(milliseconds: 300)) // задержка
.listen((value) => print(value));
Важные правила работы со Stream
- Всегда отписывайтесь — вызывайте
cancel()на subscription вdispose(), иначе будут утечки памяти - Обрабатывайте ошибки — используйте параметр
onErrorвlisten()илиcatchError() - Используйте StreamBuilder — он автоматически управляет подпиской в Flutter
- Выбирайте правильный тип — Single-subscription для простых случаев, broadcast для множественных слушателей
Stream — это необходимый инструмент для построения асинхронных, реактивных приложений на Flutter.