如何在 Async/Dart 的 List.forEach()中等待

我正在编写某种 bot (命令行应用程序) ,当我使用“ forEach”方法时,我在异步执行方面遇到了麻烦。 下面是我正在尝试做的事情的一个简化代码:

main() async {
print("main start");
await asyncOne();
print("main end");
}


asyncOne() async {
print("asyncOne start");
[1, 2, 3].forEach(await (num) async {
await asyncTwo(num);
});
print("asyncOne end");
}


asyncTwo(num) async
{
print("asyncTwo #${num}");
}

输出如下:

main start
asyncOne start
asyncOne end
main end
asyncTwo #1
asyncTwo #2
asyncTwo #3

我想说的是:

main start
asyncOne start
asyncTwo #1
asyncTwo #2
asyncTwo #3
asyncOne end
main end

如果有人知道我做错了什么,我会很感激的。

29435 次浏览

I don't think it's possible to achieve what you want with the forEach method. However it will work with a for loop. Example;

asyncOne() async {
print("asyncOne start");
for (num number in [1, 2, 3])
await asyncTwo(number);
print("asyncOne end");
}

You can't use forEach for this because it doesn't actually look at the return values of its callbacks. If they are futures, they will just be lost and not awaited.

You can either do a loop like Steven Upton suggested, or you can use Future.wait if you want the operations to run simultaneously, not one after the other:

asyncOne() async {
print("asyncOne start");
await Future.wait([1, 2, 3].map(asyncTwo));
print("asyncOne end");
}

You need to use Future.forEach.

main() async {
print("main start");
await asyncOne();
print("main end");
}


asyncOne() async {
print("asyncOne start");
await Future.forEach([1, 2, 3], (num) async {
await asyncTwo(num);
});
print("asyncOne end");
}


asyncTwo(num) async
{
print("asyncTwo #${num}");
}

I know this is an old question, but I'll leave here a new answer, hoping this help someone in the future.

You can use forEach for what you're trying to achieve by doing something like this:

  asyncOne() async {
print("asyncOne start");
await Future.forEach([1, 2, 3],(num) async {
await asyncTwo(num);
});
print("asyncOne end");
}

use forEach loop even if you have created a list of custom class.

    lol() async {
await Future.forEach(myListofFood,(Food food) async {
await secondaryfuncton(food);
});
}

If you need iterate a Map, you can use:

await Future.forEach(myMap.keys, (key) async {
final value = data[key];
}

The advantage of this solution, is that it can be used with mapIndexed

await Future.wait([1, 2, 3].map(  // or mapIndexed(
(num) async {
await asyncTwo(num);
}));