如何恢复Dart生成器?复用同一生成器无法继续取值求助
问题分析与解决方案
你遇到的问题核心在于async*生成器创建的是冷流,转成广播流后,当所有订阅取消时,源流会被关闭,生成器执行终止。
具体逻辑:
- 调用
iter()得到单订阅冷流,转成广播流myIter后,第一个await for订阅启动,生成器开始输出0-3,随后break退出循环,订阅取消。 - 此时广播流无活跃订阅,触发源流取消操作,生成器停止执行,整个流被关闭。
- 第二个
await for订阅时,流已处于关闭状态,因此无法进入循环。
解决方案
要复用同一个生成器并获取后续值,需让生成器执行不依赖订阅状态,这里推荐用StreamController手动接管事件分发,确保生成器持续生成值,广播流可随时订阅获取后续事件:
Stream<int> iter() async* { for (int i = 0; i < 100; i++) { print('generated'); yield i; } } void main() async { final controller = StreamController<int>(); // 独立启动生成器,持续向controller发送事件 void runGenerator() async { await for (final num in iter()) { if (!controller.isClosed) { controller.add(num); } else { break; } } controller.close(); } runGenerator(); // 转成广播流支持多订阅 final myIter = controller.stream.asBroadcastStream(); int counter = 0; await for (var i in myIter) { print(i); counter++; if (counter > 3) break; } counter = 0; await Future.delayed(const Duration(seconds: 1)); await for (var i in myIter) { print(i); counter++; if (counter > 3) break; } // 程序结束前关闭controller释放资源 await controller.close(); }
这段代码的核心逻辑:
StreamController作为中间层,接收生成器的所有输出事件- 生成器独立运行,不受订阅状态影响,直到生成完所有值或controller被关闭
- 广播流
myIter可被多次订阅,随时获取当前及后续的生成值
运行后会先输出0-3,等待1秒后输出4-7,同时生成器会持续打印generated直到完成100次循环。
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

