Хобрук: Ваш путь к мастерству в программировании

Ранее добавленное значение Stream для возврата при прослушивании (Broadcast Stream)

У меня есть пользовательский StreamController<int>:

final StreamController listener = StreamController<int>.broadcast();

После инициализации я передаю значение в поток

listener.add(7);

После отправки значения я установил прослушиватель Stream

listener.stream.listen((val) {
    print(val);
});

Ожидаемое поведение состоит в том, что прослушиватель вернет ранее установленное значение, однако это не так. Только если я установлю значение после установки слушателя, будет вызван слушатель.

Как я могу добиться такого поведения?

(Редактировать: необходимо поддерживать несколько слушателей)

09.06.2020

  • Не делать поток широковещательным? Смысл вещания в том, чтобы разрешить несколько слушателей, но это также приведет к отбрасыванию любых событий, если слушателей нет: api.dart.dev/stable/2.8.4/dart-async/StreamController/ 09.06.2020
  • @ julemand101 хорошо, хорошее решение, это сработало. Однако другим требованием является то, что слушателей может быть несколько. Если у вас есть решение для этого, рассмотрите возможность написания ответа :) 09.06.2020
  • Возможно, вызовите asBroadcastStream на Stream, возвращенном из StreamController: api. dart.dev/stable/2.8.4/dart-async/Stream/ — возвращаемый поток подпишется на этот поток, когда будет добавлен его первый подписчик, и останется подписанным до тех пор, пока этот поток не закончится или обратный вызов не отменит подписка. 09.06.2020
  • Но да, если вы в какой-то момент вернетесь к нулю подписчиков, события снова будут сброшены. Другое решение — сделать что-то вручную, где вы сами управляете списком подписчиков и кладете события в буфер, если подписчиков нет. 09.06.2020
  • Ну, на самом деле, есть подсказка по asBroadcastStream: используйте обратные вызовы, например, для приостановки базовой подписки при отсутствии подписчиков, чтобы предотвратить потерю событий, или отмены подписки, когда нет слушателей. 09.06.2020
  • Кажется, это работает отлично! Спасибо за вашу помощь @julemand101. Если хотите, можете написать ответ, и я приму его. 09.06.2020

Ответы:


1

Во-первых, не делайте Stream трансляцией stream, так как определение этого типа потока состоит в том, чтобы разрешить несколько подписчиков, но все события будут потеряны, если нет текущих подписчиков.

После этого взгляните на asBroadcastStream. на Stream вернулся из StreamController. Этот метод позволяет реализовать логику, в которой поток сначала прослушивается после первого подписчика, а также позволяет реализовать такую ​​логику, как приостановка потока, если подписчиков больше нет.

09.06.2020
  • Это работает только для первого слушателя. Причина, по которой контроллер потока раньше был широковещательным, заключалась в том, что его нужно слушать несколькими слушателями одновременно, и все они должны получать события, когда они начинают слушать. В этом смысле не имеет значения, используете ли вы asBroadcastStream или широковещательный контроллер. 09.06.2020
  • подходящей альтернативой является BehaviorSubject RxDart, это класс выполняет именно ту работу, о которой я просил 10.06.2020

  • 2

    Вы можете использовать для этого обратный вызов StreamController onListen, так как он будет вызываться каждый раз, когда кто-то подписывается.

    class StreamExample {
      late final StreamController<dynamic> _controller;
      dynamic _val;
    
      StreamExample() {
        _controller = StreamController.broadcast();
        _controller.onListen = () => _controller.add(_val);
      }
    
      /// Example setter for value which works 
      /// like [ChangeNotifier] for [Stream] listeners.
      void set val(value) {
        _val = value;
        _controller.add(value);
      }
    
      Stream<dynamic> get stream => _controller.stream;
    }
    
    18.05.2021
    Новые материалы

    Решения DBA Metrix
    DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

    Начало работы с Блум
    Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...