Dart广播StreamController是否支持多生产者?如何理解add调用限制?
关于Dart广播StreamController多生产者调用add方法的疑问与解答
问题核心
能不能让多个异步操作调用同一个广播StreamController的controller.add(myEvent)方法?也就是允不允许多个生产者向同一广播流发送事件?
官方文档有这样的表述:
不允许在前一次add、addError或close调用返回前再次调用这些方法。
但add是返回void的同步操作,该怎么理解这句话?
解答
结论:允许多个生产者向同一广播StreamController发送事件,但必须避免重入调用
对文档限制的正确理解
文档里的限制并不是禁止多生产者,而是禁止重入调用——也就是不能在add、addError或close方法的执行过程中,再次发起这些方法的调用。
虽然add是同步方法,但只要多个异步操作的add调用是在事件循环的不同任务(微任务/宏任务)中执行,它们的调用就是串行的:前一次add执行完毕并返回后,下一次调用才会开始,完全符合文档要求。
合法示例
多个异步任务分别调用add,彼此执行时间不重叠:
final controller = StreamController.broadcast(); // 异步任务1 Future.delayed(Duration(seconds: 1), () { controller.add('来自任务1的事件'); }); // 异步任务2 Future.delayed(Duration(seconds: 2), () { controller.add('来自任务2的事件'); });
非法示例(重入调用)
在add触发的监听回调中再次调用add,此时前一次add还未执行完成:
final controller = StreamController.broadcast(); controller.stream.listen((event) { // 错误:重入调用,违反文档限制 controller.add('重入事件'); }); controller.add('初始事件');
这种情况会触发运行时错误,因为前一次add调用还在执行(正在处理监听回调),就发起了新的add调用。
内容的提问来源于stack exchange,提问作者ig-dev
相关产品推荐
相关产品推荐

