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

嵌套异步函数问题:Dart中forEach异步操作未完成就提前返回如何解决

问题根源

Dart 的 Iterable.forEach 不支持等待内部异步回调执行完成:你在 forEach 中传入的 async 函数会返回独立的 Future,但 forEach 本身不会等待这些 Future 执行完毕,就会直接继续执行后续的 return 逻辑,所以返回时 feedItems 还未被填充数据,自然为空。你看到的打印内容是后续异步任务执行完成后输出的,所以数据正常。

修复方案

将 forEach 遍历替换为 Future.wait + map 的组合,主动等待所有二次查询任务全部执行完成后再返回结果,修正后代码如下:

static getFriendsRequests({required id}) async {
  QuerySnapshot snapshot = await friendsRef
      .doc(id)
      .collection('received')
      .get();

  // 把每个文档的异步处理逻辑封装为Future,用Future.wait等待全部执行完成
  List<friendRequestItem> feedItems = await Future.wait(snapshot.docs.map((doc) async {
    DocumentSnapshot extracted = await usersRef.doc(doc.reference.id).get();
    MyUser tempUser = MyUser.fromJsonDocument(extracted);
    String url = tempUser.profilePictureURL ?? '';
    FriendRequest fr = FriendRequest(
        userID: tempUser.userID, 
        uniqueName: tempUser.uniqueName,
        name: tempUser.name, 
        mediaURL: url);
    print(fr.uniqueName + fr.name + fr.userID + fr.mediaURL);
    return friendRequestItem(friendReq: fr);
  }));

  return feedItems;
}

补充说明

  • snapshot.docs.map 会把每个文档转换为一个 Future<friendRequestItem>,Future.wait 会并行执行所有这些异步任务,全部执行完成后会直接返回组装好的对象列表,此时返回的列表已经完成数据填充,不会再出现空列表问题。
  • 原有三目运算符逻辑可以简化为 String url = tempUser.profilePictureURL ?? '',逻辑等价且写法更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:03:02