Appel async/await fonctions en parallèle
Comme je le comprends, dans l'ES7/ES2016 mettre plusieurs await
's dans le code du travail similaire à chaînage .then()
avec des promesses, ce qui signifie qu'elles s'exécutent l'une après l'autre, plutôt que dans parallerl. Ainsi, par exemple, nous avons ce code:
await someCall();
await anotherCall();
Dois-je comprends bien que anotherCall()
sera appelée que lorsque someCall()
est terminé? Quelle est la façon la plus élégante de les appeler en parallèle?
Je veux l'utiliser dans un Nœud, alors peut-être il y a une solution avec async bibliothèque?
EDIT: je ne suis pas satisfait de la solution apportée à cette question: Ralentissement en raison de la non-parallèles en attente de promesses dans les générateurs asynchrones, car il utilise des générateurs et je veux parler d'un usage plus général cas.
- Javascript ne s'exécute pas en parallèle. Vous devez commencer un nouveau contexte comme un travailleur pour le faire,
- Alors, où voulez-vous l'utiliser,
async/await
ne sera pas inclus dans l'ES7, soit, mais est actuellement pris en charge dans Babel, c'est que le seul endroit où vous avez l'intention d'utiliser cette - C'est incorrect, le Javascript ne s'exécute en parallèle dans son contexte propre.
- il ne, au moins, la manière dont les OP, lorsque deux opérations asynchrones sont en cours d'exécution simultanément, mais pas dans ce cas, ce que je voulais écrire est qu'ils fonctionnent en série, la première
await
attendre la première fonction à remplir entièrement avant l'exécution de la deuxième. - c'est pourquoi, quelque chose au plus profond de mon inconscient, dit - il ne peut pas être vrai.
- Peut-être que je suis confus, mais de les exécuter en parallèle, pourquoi utiliser
await
, si elles le retour des promesses, pourquoi ne pas simplement utiliser un seulPromise.all
avec unthen
gestionnaire ->Promise.all([someCall(), anotherCall()]).then(function(values) {...
- Non, je suis désolé mais vous vous trompez. Si l'on pouvait vous seriez en mesure de fournir un exemple de la façon dont javascript serait poignée écrit à la même variable en même temps. Javascript n'est pas conçu pour s'exécuter en parallèle à cause de cette raison. Vous ne pouvez pas verrouiller les variables javascript.
- il est mono-thread, mais cette limitation ne s'applique pas aux méthodes asynchrones, ils peut exécuter en même temps, et renvoyer la réponse quand elles sont faites, c'est à dire ce que l'OP veut dire par "parallèle".
- Qui n'est pas parallèle, async objets d'exécuter du code natif pas de javascript ni tout asynchrone en fonction appelée jusqu'à l'exécution en cours est terminée. Tout ce qu'ils peuvent faire est de placer des appels sur la pile d'appel pour attendre l'exécution séquentielle.. Il est trompeur de décrire asynchrone en javascript et des objets en parallèle. L'OP demander si les deux méthodes peuvent être appelées en parallèle plutôt que de façon séquentielle, Ce n'est pas possible dans un seul contexte javascript, Une fonction doit être exécuté avant les autres.
- Je pense qu'il est assez clair que les OP se demander, à l'aide de la async/await motif que les fonctions exécutées en série, même si elles sont asynchrones, de sorte que la première serait complètement terminé avant que la seconde est appelée etc. L'OP se demande comment appeler la fonction en parallèle, et comme ils sont clairement asynchrone, l'objectif est de les exécuter simultanément, c'est à dire en parallèle, par exemple faire deux requêtes ajax simultanément, ce qui n'est pas un problème du tout en javascript, comme la plupart des méthodes asynchrones, comme vous l'avez remarqué, il s'exécute en code natif, et utilise plusieurs threads.
- Comment sur "exécuter deux tâches asynchrones simultanément" au lieu de "appeler les fonctions en parallèle"?
- Nous ne sommes pas en discussion sur async tâches, mais JS fonctions. Pour exécuter la fonction deux en "parallèle" le contexte initial doit frayer un
ChildProcess
ou unWorker
viaCluster
, Dans chaque cas, un nouveau contexte et JS moteur (V8) sont instanciés. Selon la fonction, ce ne peut pas être de tout avantage. Async tâches ne peuvent passer des appels sur la pile des appels (AKA eventQueue), ils ne peuvent pas appeler JS directement. Toute exécution dans le contexte actuel va bloquer ces appels. C'est le JS fonctionne de la question est inquiète, et nous devons faire attention à ne pas utiliser trompeuse de la terminologie. - Une promesse de retour asynchrone fonction est toujours liée à un certain type de tâche pour moi, et c'est ce que l'OP se pose au sujet de. Bien sûr, sa terminologie peut ne pas être précis à 100%, mais nous comprenons tous ce qu'il veut faire, et cela devrait suffire.
- ce n'est pas un doublon de la question — c'est précisément à propos de async/await syntaxe et natif
Promise
s. La question est liée au sujet de la bluebird bibliothèque avec des générateurs & le rendement. Conceptuellement similaire peut-être, mais pas dans la mise en œuvre. - C'est conceptuellement exactement la même. La syntaxe n'a pas vraiment d'importance.
- Les rappels sont également de faire la même chose que des promesses et async/await, c'est juste la syntaxe qui est différent. Je ne veux pas utiliser ni les rappels, ni de générateurs, cependant. La question est plus précisément sur async/await syntaxe.
- La syntaxe très important. Pour une personne qui n'a jamais utilisé des générateurs ou bluebird liés question est complètement inutile.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez vous attendent sur Promesse.tous les():
Promise.all
dans ce cas?[result1, result2] = Promise.all([async1(), async2()]);
= await Promise.all
?let
,const
, ouvar
comme dans:let [result1, result2] = await Promise.all([async1(), async2()]);
const results = await Promise.all(promises.map(promise => promise.catch(error => error)));
oùpromises
est un tableau de promesses. Puisque, techniquement, tout est régler maintenant, pour vérifier si quelque chose a échoué, itérer surresults
et de vérifier si l'élément est uninstanceof Error
. (en supposant que u rejeter avec une Erreur).TL;DR
Utilisation
Promise.all
pour le montage en parallèle des appels de fonction, la réponse à des comportements pas correctement lorsque l'erreur se produit.D'abord, exécutez tous les appels asynchrones à la fois et d'obtenir toutes les
Promise
objets. Deuxièmement, l'utilisationawait
sur lePromise
objets. De cette façon, pendant que vous attendez pour la premièrePromise
pour résoudre les autres appels asynchrones sont toujours en progression. Dans l'ensemble, vous ne pourront pas attendre aussi longtemps que le plus lent appel asynchrone. Par exemple:JSbin exemple: http://jsbin.com/xerifanima/edit?js console
Mise en garde: Il n'a pas d'importance si le
await
les appels sont sur la même ligne ou sur plusieurs lignes, aussi longtemps que le premierawait
appel arrive après tous les appels asynchrones. Voir JohnnyHK commentaire.Mise à jour: cette réponse a un autre moment dans la gestion d'erreur en fonction de la @bergi réponse, il ne PAS jeter l'erreur que l'erreur se produit, mais après toutes les promesses sont exécutées.
Je compare le résultat avec @jonny conseil:
[result1, result2] = Promise.all([async1(), async2()])
, vérifier l'extrait de code suivantJS:
[someResult, anotherResult] = [await someResult, await anotherResult]
si vous modifiezconst
àlet
.await
déclarations en série, non? C'est l'exécution est suspendue jusqu'à ce que le premierawait
résout, puis se déplace sur le second.Promise.all
exécute en parallèle.Promise.all
de prétendre à exécuter les deux appel asynchrone simultanément.Promise.all
. Si chaque demande est un appel réseau,await someResult
devront être résolus avantawait anotherResult
est même pas commencé. À l'inverse, dansPromise.all
les deuxawait
appels peut être commencé avant que l'un des deux est résolu.new
opérateur, le constructeur est appelé dans la synchronisation. C'est la raison pour laquelle nous voyonsstart call starts
&second call starts
immédiatement.const finalResult = [await someResult, await anotherResult]
Uncaught (in promise) Error: Whoops! at Promise.then
const [someResp, anotherResp] = await Promise.all([someResult(), anotherResult()]);
Il fera de ces deux appels en parallèle, et puis passer à la ligne suivante lorsque les deux réponses sont venus.results = [await firstPromise, await secondPromise, await thirdPromise]
. Dans cet exemple,results
est affecté après tous les qui attend ont décidé, et qu'ils sont en cours de traitement depuis le moment de la première exécution, avant d'être attendue dans le tableau.asyncInArray()
parce que dans le scénario négatif try/catch ne sera pas attraper les erreurs de tous les async tâches en parallèle et vous allez vous retrouver avec non gérée rejets d'avertissement. La seule façon correcte pour async tâches en parallèle est d'utiliser Promesse.tous les() de sorteasyncInPromiseAll()
dans cette réponse.Mise à jour:
L'original de la réplique fait, il est difficile (voire impossible dans certains cas) afin de gérer correctement la promesse des rejets. La bonne solution est d'utiliser
Promise.all
:Réponse originale à cette question:
Assurez-vous d'appeler les deux fonctions avant de vous y attendent soit un:
await
ensuite les résoudre dans des valeurs réelles.Promise.all
), à la différence de l'Original de la réponse", alors ne prenez pas @Bergi mots trop fortement. C'est en effet la meilleure réponse ici, à mon humble avis.Il y a une autre façon, sans Promesse.tous les() pour le faire en parallèle:
Tout d'abord, nous avons 2 fonctions pour imprimer les numéros:
C'est séquentielle:
C'est parallèle:
J'ai créé un résumé des tests de différents moyens de résoudre les promesses, avec des résultats. Il peut être utile de voir les options qui conviennent.
La solution intuitive
JS:
Avec ES6 vous pouvez même le faire à l'étape 2
PS: Vous pouvez également vous attendent à l'intérieur de calculs
"gestion des exceptions"
La
.catch(e => e)
attrape l'erreur et le passe en bas de la chaîne, permettant à la promesse de résoudre, au lieu de rejetant.JS:
parallel()
Je vote pour:
Être conscient du moment où vous appelez des fonctions, il peut provoquer résultat inattendu:
Mais en suivant toujours les déclencheurs de la demande pour créer un nouvel Utilisateur
else
bloc.J'ai créer une fonction d'assistance waitAll, peut-être, ça peut le faire plus doux.
Il ne fonctionne que dans nodejs pour l'instant, pas dans le navigateur chrome.
for
boucle de manière séquentielle attend chaque promesse et ajoute le résultat au tableau.