Flutter中Stream listener与StreamController异步通信未按预期运行问题
代码问题诊断及修复方案
核心错误点
- 实例不统一:
_MyHomePageState中创建的NumberSpeaker和NumberListener内部自行创建的NumberSpeaker是完全独立的两个实例,对应的StreamController互不连通,监听器无法接收到发送端的事件。 - 事件未注入控制器:
NumberSpeaker的speak方法用async*生成的事件没有传入你声明的StreamController,控制器从未向外发送过任何事件。此外async*修饰的生成器函数只有被订阅时才会执行内部逻辑,你直接调用speaker.speak()没有处理返回值,内部循环根本不会运行,所以不会打印Topic相关日志。 - 监听逻辑冗余错误:
NumberListener的listen方法同时使用await for和listen双层订阅stream,逻辑混乱,无法正常接收事件。
修正代码
1. 修正 speaker.dart
import 'dart:async'; class NumberSpeaker { final StreamController<int> _streamController = StreamController<int>(); // 非空的Stream,不需要加? Stream<int> get stream => _streamController.stream; int _topicNumber = 1; final int _numberOfTopics = 20; void speak() async { while (_topicNumber < _numberOfTopics) { // 将事件注入StreamController,监听器才能收到 _streamController.add(_topicNumber); print('Topic$_topicNumber loud and clear'); _topicNumber++; // 可加延迟模拟实际事件间隔,不加的话事件会瞬间发送完成 await Future.delayed(const Duration(seconds: 1)); } _streamController.close(); } }
2. 修正 listener1.dart
import 'dart:async'; import 'package:streams/speaker.dart'; class NumberListener { final Stream<int> speakerStream; // 从外部传入同一份Stream,保证和发送端是同一个实例 NumberListener(this.speakerStream); void listen() { print('Awaiting anxiously for the speaker to start speaking!'); // 直接订阅Stream即可,不需要双层监听 speakerStream.listen( (topic) { print('Great topic$topic. APPLAUSE!!!!'); }, onError: (err) { print('Error: $err'); }, cancelOnError: false, onDone: () { print('Thunderous APPLAUSE!!!!!'); } ); } }
3. 修正State构造方法,统一实例
_MyHomePageState() : super(){ print('_MyHomePageState constructor executing'); // 只创建一个Speaker实例 final speaker = NumberSpeaker(); // 将同一份Stream传给监听器 final listener1 = NumberListener(speaker.stream); listener1.listen(); speaker.speak(); }
内容的提问来源于stack exchange,提问作者SpeedyVV
相关产品推荐
相关产品推荐

