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

Flutter中async*函数使用yield*后for循环不继续执行问题

问题根因

yield*的语义是完全委托目标Stream的事件推送,只有被委托的Stream触发done完成事件后,当前生成器函数才会继续执行yield*之后的逻辑。
你代码中调用的snapshots()是Firestore提供的实时监听流,这个流会长期存活:只要不主动取消订阅,它会持续推送集合的实时变更,永远不会主动触发完成事件。因此第一次循环执行到yield*时,函数会永久停在第一个partner的流监听逻辑上,永远不会进入下一轮循环处理剩余的列表元素。

解决方案

根据实际业务需求二选一即可:

场景1:需要持续监听所有partner的referral集合实时变更

如果要同时监听所有partner的集合变化,不要用yield*逐个等待流完成,直接合并所有子流统一推送即可:

import 'dart:async';
// 其余业务依赖导入省略

static Stream<List<Referral>> streamRefs(
    List<Map<String, dynamic>> partnerLocations) async* {
  final streamGroup = StreamGroup<List<Referral>>();
  for (var partner in partnerLocations) {
    debugPrint("初始化partner监听: $partner");
    final singlePartnerStream = FirebaseFirestore.instance
        .collection('partners')
        .doc('kenya')
        .collection(partner['category'])
        .doc(partner['branchID'])
        .collection("referrals")
        .snapshots()
        .map((snapshot) => snapshot.docs
            .map((document) => Referral.fromJson(
                  document.data(),
                  document.id,
                  partner['branchID'],
                  partner['category'],
                ))
            .toList());
    streamGroup.add(singlePartnerStream);
  }
  yield* streamGroup.stream;
}

如果需要把所有partner的referral数据合并为一个全量列表推送,可以维护一个Map记录每个partner对应的最新数据,任意子流有更新时重新拼接全量列表再yield即可。

场景2:只需要一次性拉取每个partner的referral数据,不需要实时监听

这种场景直接用get()替换snapshots()获取一次性查询结果即可,循环会正常顺序执行:

static Stream<List<Referral>> streamRefs(
    List<Map<String, dynamic>> partnerLocations) async* {
  for (var partner in partnerLocations) {
    debugPrint("拉取partner数据: $partner");
    final snapshot = await FirebaseFirestore.instance
        .collection('partners')
        .doc('kenya')
        .collection(partner['category'])
        .doc(partner['branchID'])
        .collection("referrals")
        .get();
    final refList = snapshot.docs
        .map((document) => Referral.fromJson(
              document.data(),
              document.id,
              partner['branchID'],
              partner['category'],
            ))
        .toList();
    yield refList;
  }
}

内容的提问来源于stack exchange,提问作者user10675368

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:09:26