使用map的Broadcast Stream生成器未发射值问题求助
问题原因
你的stringStream通过async*生成器创建,调用其listen方法时,生成器的执行会被调度到微任务队列,而非同步执行。而你同步调用streamController.sink.add添加的事件,会被立即放入事件队列——此时生成器尚未完成对广播流的订阅。
广播流的核心特性是:仅向事件添加时已存在的活跃监听者发送事件,后续订阅的监听者无法获取已在队列中的事件。因此你通过stringStream添加的监听者,错过了提前放入队列的1、2、3这三个事件。
解决方案
方案1:直接返回映射后的广播流(推荐)
去掉async*生成器,直接返回广播流的映射结果,这样调用listen时会立即完成订阅,不会错过事件:
import 'dart:async'; final streamController = StreamController<int>.broadcast(); // 直接返回映射后的广播流 Stream<int> get stringStream => streamController.stream.map((i) => i * i); void main() { streamController.stream.listen(print); stringStream.listen(print); streamController.sink.add(1); streamController.sink.add(2); streamController.sink.add(3); }
方案2:延迟发送事件(保留async*场景)
如果必须保留async*生成器,可以将事件发送逻辑延迟到微任务队列,确保生成器先完成订阅:
import 'dart:async'; final streamController = StreamController<int>.broadcast(); Stream<int> get stringStream async* { yield* streamController.stream.map((i) => i * i); } void main() { streamController.stream.listen(print); stringStream.listen(print); // 将事件发送放到微任务队列,确保生成器先完成订阅 Future.microtask(() { streamController.sink.add(1); streamController.sink.add(2); streamController.sink.add(3); }); }
内容的提问来源于stack exchange,提问作者MikkelT
相关产品推荐
相关产品推荐

