如何等待 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
预期输出
as you can see i want to use to wait until foreach loop of map complete to complete then i want to print third
expected Output
Second!
Third!
Third!
third
推荐答案
Iterable.forEach
、Map.forEach
和 Stream.forEach
旨在为副作用在集合的每个元素上执行一些代码.它们采用具有 void
返回类型的回调.因此,那些.forEach
方法不能使用回调返回的任何值,包括返回的Future
.如果您提供一个返回 Future
的函数,该 Future
将丢失,并且您将无法在完成时收到通知.因此,您不能等待每个迭代完成,也不能等待所有迭代完成.
Iterable.forEach
, Map.forEach
, and Stream.forEach
are meant to execute some code on each element of a collection for side effects. They take callbacks that have a void
return type. Consequently, those .forEach
methods cannot use any values returned by the callbacks, including returned Future
s. If you supply a function that returns a Future
, that Future
will be lost, and you will not be able to be notified when it completes. You therefore cannot wait for each iteration to complete, nor can you wait for all iterations to complete.
不要将 .forEach
与异步回调一起使用.
Do NOT use .forEach
with asynchronous callbacks.
相反,如果您想顺序等待每个异步回调,只需使用普通的for
循环:
Instead, if you want to wait for each asynchronous callback sequentially, just use a normal for
loop:
for (var mapEntry in gg.entries) {
await Future.delayed(const Duration(seconds: 5));
}
(一般来说,我建议在 .forEach
上使用普通的 for
循环 除特殊情况外.Effective Dart 有一个非常相似的推荐.)
(In general, I recommend using normal for
loops over .forEach
in all but special circumstances. Effective Dart has a mostly similar recommendation.)
如果您真的更喜欢使用 .forEach
语法并希望连续等待每个 Future
,您可以使用 Future.forEach
(确实 期望返回 Future
s) 的回调:
If you really prefer using .forEach
syntax and want to wait for each Future
in succession, you could use Future.forEach
(which does expect callbacks that return Future
s):
await Future.forEach(
gg.entries,
(entry) => Future.delayed(const Duration(seconds: 5)),
);
如果你想让你的异步回调可能并行运行,你可以使用 Future.wait
:
If you want to allow your asynchronous callbacks to possibly run in parallel, you can use Future.wait
:
await Future.wait([
for (var mapEntry in gg.entries)
Future.delayed(const Duration(seconds: 5)),
]);
参见 https://github.com/dart-lang/linter/issues/891 请求分析器警告,如果尝试使用异步函数作为 Map.forEach
或 Iterable.forEach
回调(以及许多类似的 StackOverflow 问题).
See https://github.com/dart-lang/linter/issues/891 for a request for an analyzer warning if attempting to use an asynchronous function as a Map.forEach
or Iterable.forEach
callback (and for a list of many similar StackOverflow questions).
这篇关于如何等待 forEach 完成异步回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!