How to Async/await in List.forEach() in Dart

FlutterDartAsynchronousForeach

Flutter Problem Overview


I'm writing some kind of bot (command line application) and I'm having trouble with async execution when I'm using the "forEach" method. Here is a simplified code of what I'm trying to do :

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}");
}

And here is the output :

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

What I'm trying to get is :

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

If someone knows what I'm doing wrong I would appreciate it.

Flutter Solutions


Solution 1 - Flutter

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}");
}

Solution 2 - Flutter

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");
}

Solution 3 - Flutter

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");
}

Solution 4 - Flutter

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");
}

Solution 5 - Flutter

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);
  });
}

Solution 6 - Flutter

If you need iterate a Map, you can use:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionaelayebView Question on Stackoverflow
Solution 1 - FlutterStephaneView Answer on Stackoverflow
Solution 2 - FlutterstwuptonView Answer on Stackoverflow
Solution 3 - FlutterlrnView Answer on Stackoverflow
Solution 4 - FlutterTmRochaView Answer on Stackoverflow
Solution 5 - FlutterzuriView Answer on Stackoverflow
Solution 6 - FlutterÁlvaro AgüeroView Answer on Stackoverflow