You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:05:59