Можно ли добавить элемент в список, содержащийся в потоке в Dart?
Проблема
у меня есть Stream<List>
который прослушивается в нескольких классах, и мне нужно, чтобы все классы получали обновленный поток после добавления значения в список в Stream.
Что я пробовал
void main() {
StreamedList<String> dataStream = StreamedList();
dataStream.data.listen((list) => print(list));
dataStream.updateList(['Apple', 'Orange']);
dataStream.addToList('Mango'); // This is what I want to do
}
Это код для StreamList
учебный класс
class StreamedList<T> {
StreamController<List<T>> _controller = StreamController.broadcast();
Stream<List<T>> get data => _controller.stream;
void updateList(List<T> list) {
_controller.sink.add(list);
}
void addToList(T value) {
// Is it possible to do this?
// List<T> dataList = await _controller.data;
// dataList.add(value);
// updateList(dataList);
}
void dispose() {
_controller.close();
}
}
Я пробовал разные API из dart:async
библиотека, включая Stream.first
и т. д., которые возвращают Future<List<T>>
. Но проблема в том, что это будущее разрешается только после того, как что-то будет добавлено в поток позже (например, путем вызоваStreamedList.updateList
функция).
Вопрос
Как добавить одно значение к List
внутри Stream
?
1 ответ
Вы не понимаете, что за Stream
делает. Он не "содержит" данных. Он просто принимает данные на одном конце (приемник) и распространяет их на другой конец (поток), а любые слушатели получают доступ к объекту потоковой передачи. Попытка "вставить элемент в список в потоке" не имеет никакого концептуального смысла.
Если вы хотите добавить в список дополнительный элемент, возьмите старый список, добавьте к нему элемент, а затем повторно добавьте список в поток.
class StreamedList<T> {
StreamController<List<T>> _controller = StreamController.broadcast();
Stream<List<T>> get data => _controller.stream;
List<T> _list = [];
void updateList(List<T> list) {
_list = list;
_dispatch();
}
void addToList(T value) {
_list.add(value);
_dispatch();
}
void _dispatch() {
controller.sink.add(_list);
}
void dispose() {
_list = null;
_controller.close();
}
}
Если вы хотите быть вдвойне безопасным, вы можете воссоздавать список после каждого addToList
, поскольку, если слушатель захватил список в другом месте и изменил его содержимое, это повлияло бы на _list
также.
void addToList(T value) {
_list = [..._list, value];
_dispatch();
}