Можно ли добавить элемент в список, содержащийся в Stream в Dart? - PullRequest
0 голосов
/ 07 февраля 2020

Проблема

У меня есть Stream<List>, который прослушивается в нескольких классах, и мне нужно, чтобы все классы получали обновленный поток после добавления значения в список в Поток.

Что я пробовал

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, et c. которые возвращают Future<List<T>>. Но проблема в том, что это Будущее разрешается только после того, как что-то будет добавлено в Поток позже (например, путем вызова функции StreamedList.updateList).

Вопрос

Как сделать Я добавляю одно значение к List внутри Stream?

1 Ответ

2 голосов
/ 07 февраля 2020

Вы не понимаете, что делает Stream. Он не «содержит» данные. Он просто принимает данные на одном конце (приемнике) и распространяет их на другом конце (в потоке), и любые слушатели получают доступ к потоковому объекту. Попытка «вставить элемент в список в потоке» не имеет никакого концептуального смысла.

Если вы хотите создать sh список с дополнительным элементом, возьмите старый список, добавьте элемент к нему, а затем повторно добавьте список в поток.

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...