Можно ли добавить элемент в список, содержащийся в потоке в 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();
}
Другие вопросы по тегам