Pour autant que je sache, dans ES7 / ES2016, mettre plusieurs await
dans le code fonctionnera de manière similaire au chaînage .then()
avec des promesses, ce qui signifie qu'ils s'exécuteront les uns après les autres plutôt qu'en parallèle. Ainsi, par exemple, nous avons ce code:
await someCall();
await anotherCall();
Dois-je comprendre correctement que anotherCall()
sera appelé uniquement une fois someCall()
terminé? Quelle est la manière la plus élégante de les appeler en parallèle?
Je veux l'utiliser dans Node, alors peut-être qu'il y a une solution avec la bibliothèque asynchrone?
EDIT: Je ne suis pas satisfait de la solution fournie dans cette question: Ralentissement dû à l'attente non parallèle de promesses dans les générateurs asynchrones , car il utilise des générateurs et je pose des questions sur un cas d'utilisation plus général.
la source
await
attendrait que la première fonction se termine entièrement avant d'exécuter la seconde.Promise
s natifs . La question liée concerne la bibliothèque Bluebird avec générateurs et rendement. Conceptuellement similaire peut-être, mais pas dans la mise en œuvre.Réponses:
Vous pouvez attendre sur
Promise.all()
:Pour stocker les résultats:
Notez que cela
Promise.all
échoue rapidement, ce qui signifie que dès qu'une des promesses qui lui sont faites rejette, alors la chose entière rejette.Si, à la place, vous voulez attendre que toutes les promesses soient tenues ou rejetées, vous pouvez utiliser
Promise.allSettled
. Notez qu'Internet Explorer ne prend pas en charge nativement cette méthode.la source
[result1, result2] = Promise.all([async1(), async2()]);
= await Promise.all
?TL; DR
Utilisez
Promise.all
pour les appels de fonctions parallèles, les comportements de réponse ne sont pas correctement lorsque l'erreur se produit.Tout d'abord, exécutez tous les appels asynchrones à la fois et obtenez tous les
Promise
objets. Deuxièmement, utilisezawait
sur lesPromise
objets. De cette façon, pendant que vous attendez que le premierPromise
résolve les autres appels asynchrones progressent toujours. Dans l'ensemble, vous n'attendez que le temps de l'appel asynchrone le plus lent. Par exemple:Exemple JSbin: http://jsbin.com/xerifanima/edit?js,console
Mise en garde: Peu importe si les
await
appels sont sur la même ligne ou sur des lignes différentes, tant que le premierawait
appel se produit après tous les appels asynchrones. Voir le commentaire de JohnnyHK.Mise à jour: cette réponse a un timing différent dans la gestion des erreurs selon la réponse de @ bergi , elle ne jette PAS l'erreur car l'erreur se produit mais après que toutes les promesses ont été exécutées. Je compare le résultat avec le conseil de @ jonny:,
[result1, result2] = Promise.all([async1(), async2()])
vérifiez l'extrait de code suivantla source
[someResult, anotherResult] = [await someResult, await anotherResult]
si vous passezconst
àlet
.await
déclarations en série, non? Autrement dit, l'exécution s'interrompt jusqu'à ce que le premier soitawait
résolu, puis passe au second.Promise.all
s'exécute en parallèle.Promise.all
. Si chaque demande est un appel réseau,await someResult
devra être résolue avantawait anotherResult
même de commencer. Inversement,Promise.all
les deuxawait
appels peuvent être démarrés avant que l'un d'eux ne soit résolu.Mise à jour:
La réponse originale rend difficile (et dans certains cas impossible) de gérer correctement les refus de promesse. La bonne solution consiste à utiliser
Promise.all
:Réponse originale:
Assurez-vous simplement d'appeler les deux fonctions avant d'attendre l'une ou l'autre:
la source
await
puis les résoudront en valeurs réelles.Il existe une autre façon sans Promise.all () de le faire en parallèle:
Tout d'abord, nous avons 2 fonctions pour imprimer les nombres:
C'est séquentiel:
C'est parallèle:
la source
Cela peut être accompli avec Promise.allSettled () , qui est similaire
Promise.all()
mais sans le comportement de sécurité rapide.Remarque : Il s'agit d'une fonctionnalité de pointe avec une prise en charge limitée du navigateur, je recommande donc fortement d' inclure un polyfill pour cette fonction.
la source
J'ai créé un résumé testant différentes façons de résoudre les promesses, avec des résultats. Il peut être utile de voir les options qui fonctionnent.
la source
Bien que définir p1, p2 et p3 ne les exécute pas strictement en parallèle, ils ne bloquent aucune exécution et vous pouvez intercepter les erreurs contextuelles avec un catch.
la source
Dans mon cas, j'ai plusieurs tâches que je veux exécuter en parallèle, mais je dois faire quelque chose de différent avec le résultat de ces tâches.
Et la sortie:
la source
attendre Promise.all ([someCall (), anotherCall ()]); comme déjà mentionné agira comme une barrière de thread (très courant dans le code parallèle comme CUDA), donc il permettra à toutes les promesses qu'il contient de s'exécuter sans se bloquer, mais empêchera l'exécution de continuer jusqu'à ce que TOUS soient résolus.
une autre approche qui mérite d'être partagée est l'async Node.js qui vous permettra également de contrôler facilement la quantité de simultanéité qui est généralement souhaitable si la tâche est directement liée à l'utilisation de ressources limitées comme appel API, opérations d'E / S, etc.
Crédits à l'auteur de l'article Medium (en savoir plus )
la source
Je vote pour:
Soyez conscient du moment où vous appelez des fonctions, cela peut entraîner un résultat inattendu:
Mais le suivi déclenche toujours une demande de création d'un nouvel utilisateur
la source
else
bloc.Je crée une fonction d'aide waitAll, peut-être que cela peut la rendre plus douce. Cela ne fonctionne que dans nodejs pour l'instant, pas dans le chrome du navigateur.
la source
for
boucle attend séquentiellement chaque promesse et ajoute le résultat au tableau.