web-dev-qa-db-fra.com

Asynchroniser / attendre dans List.forEach ()

J'écris une sorte de bot (application en ligne de commande) et j'ai des problèmes avec l'exécution asynchrone quand j'utilise la méthode "forEach". Voici un code simplifié de ce que j'essaie de faire:

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

Et voici la sortie:

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

Ce que j'essaie d'obtenir, c'est:

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

Si quelqu'un sait ce que je fais mal, je l'apprécierais.

23
aelayeb

Je ne pense pas qu'il soit possible de réaliser ce que vous voulez avec la méthode forEach. Cependant, cela fonctionnera avec une boucle for. Exemple;

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

Vous devez utiliser 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}");
}
72
Stephane

Vous ne pouvez pas utiliser forEach pour cela car il ne regarde pas réellement les valeurs de retour de ses rappels. S'ils sont des futurs, ils seront simplement perdus et non attendus.

Vous pouvez soit faire une boucle comme Steven Upton l'a suggéré, soit utiliser Future.wait si vous souhaitez que les opérations s'exécutent simultanément, pas l'une après l'autre:

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

Je sais que c'est une vieille question, mais je vais laisser ici une nouvelle réponse, en espérant que cela aide quelqu'un à l'avenir.

Vous pouvez utiliser forEach pour ce que vous essayez d'accomplir en faisant quelque chose comme ceci:

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