提问人:Jeet Agrawal 提问时间:9/3/2020 最后编辑:My CarJeet Agrawal 更新时间:2/9/2023 访问量:14835
如何等待forEach完成异步回调?
How to wait for forEach to complete with asynchronous callbacks?
问:
示例代码:
Map<String, String> gg = {'gg': 'abc', 'kk': 'kojk'};
Future<void> secondAsync() async {
await Future.delayed(const Duration(seconds: 2));
print("Second!");
gg.forEach((key, value) async {
await Future.delayed(const Duration(seconds: 5));
print("Third!");
});
}
Future<void> thirdAsync() async {
await Future<String>.delayed(const Duration(seconds: 2));
print('third');
}
void main() async {
secondAsync().then((_) {
thirdAsync();
});
}
输出
Second!
third
Third!
Third!
如您所见,我想等到地图的foreach循环完成,然后我想打印
预期的输出third
Second!
Third!
Third!
third
答:
59赞
jamesdlin
9/3/2020
#1
Iterable.forEach
、 和 旨在对集合的每个元素执行一些代码,以产生副作用。它们接受具有返回类型的回调。因此,这些 .forEach
方法不能使用回调返回的任何值,包括返回的 s。如果您提供的函数返回 ,则该函数将丢失,并且您将无法在完成时收到通知。因此,您不能等待每次迭代完成,也不能等待所有迭代完成。Map.forEach
Stream.forEach
void
Future
Future
Future
不要将 .forEach
与异步回调一起使用。
相反,如果你想按顺序等待每个异步回调,只需使用一个普通循环:for
for (var mapEntry in gg.entries) {
await Future.delayed(const Duration(seconds: 5));
}
(一般来说,我建议在除特殊情况外的所有情况下使用普通的 for 循环而不是 .forEach
。Effective Dart 有一个大致相似的建议。
如果你真的喜欢使用语法,并且想连续等待每个语法,你可以使用 Future.forEach
(它确实需要返回 s 的回调):.forEach
Future
Future
await Future.forEach(
gg.entries,
(entry) => Future.delayed(const Duration(seconds: 5)),
);
如果你想允许异步回调并发运行(可能并行运行),你可以使用 Future.wait
:
await Future.wait([
for (var mapEntry in gg.entries)
Future.delayed(const Duration(seconds: 5)),
]);
如果尝试使用异步函数作为 or 回调,请参阅 https://github.com/dart-lang/linter/issues/891,了解分析器警告的请求(以及许多类似 StackOverflow 问题的列表)。Map.forEach
Iterable.forEach
评论