嵌套异步函数问题: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
相关产品推荐
相关产品推荐

