【问题标题】:Can a Stream be listened to once at a time or once in general?Stream 可以一次听一次还是一般听一次?
【发布时间】:2019-07-04 08:21:29
【问题描述】:

我有这个 StreamController:

StreamController<Workout> _selectedWorkoutSubject = new StreamController()

我在这样的 StreamBuilder 中收听它:

StreamBuilder(
  stream: workoutBloc.selectedWorkoutStream,
  builder: (BuildContext context, AsyncSnapshot<Workout> snapshot) {
    if (snapshot.hasData) {
      return ...
    } else {
      return Text('loading...');
    }
  }
);

当我离开当前页面并返回它时,我得到了异常:Bad state: Stream has already been listened to. 我知道我一次只能执行一次,但这不是我正在做的吗?当我离开页面时,StreamBuilder 应该收集垃圾,从而释放流,以便其他东西可以收听它。

或者一个 Stream 通常只能听一次(一次不能听一次)?我知道我可以做到

StreamController<Workout> _selectedWorkoutSubject = new StreamController.broadcast();

但我试图理解为什么它不像我最初那样工作。

【问题讨论】:

标签: dart flutter bloc


【解决方案1】:

这不是“一次一个”。传统的非广播流只能听一次,永远。它只允许一个侦听器,当该侦听器取消时,流会自行清理并且不会再次工作。

一个传统的广播流可以被多次监听,但是所有并发的监听器都会收到相同的事件。

大多数Stream 构造函数和StreamControllers 创建传统的“单订阅”流或广播流。

添加了另一种创建可以多次收听的流的方法:Stream.multi 构造函数。 这样,您可以单独处理每个 listen 调用,并向它们发送您想要的任何事件,不一定是所有侦听器的相同值(每个 listen 调用都有自己的单独 StreamController)。

您可以使用它来实现广播流的行为,但您不必这样做。

除此之外,使用广播流是您的最佳选择。广播流控制器在停止拥有侦听器并再次开始拥有侦听器时确实会收到onCancelonListen 事件,因此您可以避免在没有侦听器时进行工作。 使用Stream.multi,您必须自己记录所有听众。

【讨论】:

    【解决方案2】:

    尝试一些事情:

    1. 设置流生成器的初始数据
    2. 将 StreamController 更改为 BehaviorSubject(RxDart 库)

    我认为第一个提示会对您有所帮助,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-15
      • 1970-01-01
      • 2020-02-24
      • 2012-12-27
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多