Flutter中RxDart switchMap与async*流的异常行为问题
问题原因分析
这是Dart异步生成器(async*)中yield*与await for + yield的执行逻辑差异导致的,核心区别在于流的控制方式:
1. yield* periodic的正常行为
yield*是流转发语法,它会把当前生成器的流完全委托给periodic流:
- 当
periodic发出第一个事件0时,会直接通过生成器的流传递给switchMap; switchMap随即订阅1秒周期的子流,子流的第一个事件Result:0-0会在1秒后触发;- 此时
mix.first拿到该值,整个流程结束,父流的订阅被取消,periodic不会再发出后续事件,日志符合预期。
2. await for (final period in periodic)的异常行为
await for是手动遍历流事件,生成器会主动持续拉取源流事件,不管订阅者是否需要:
- 当
periodic发出第一个事件0,生成器yield 0给switchMap后,不会暂停等待订阅者的需求,而是直接进入下一次循环,继续等待periodic的下一个事件; - 此时
switchMap已订阅子流,但生成器仍会保持对periodic的订阅,直到源流自身结束; - 如果子流的事件触发晚于
periodic的下一个事件(比如子流周期更长,或事件循环调度顺序影响),就会出现periodic先发出第二个事件1,子流才输出Result:0-0的异常日志。
本质区别
yield*是拉取式:只有订阅者需要数据时,才从源流拉取下一个事件,订阅取消时源流也会立即停止;await for + yield是推送式:生成器主动持续从源流拉取事件,即使订阅者已不需要数据,源流仍会继续发出事件。
内容的提问来源于stack exchange,提问作者Supertommino
相关产品推荐
相关产品推荐

