En JavaScript, avec les attendent à l'intérieur d'un bloc de la boucle de la boucle?
Prendre la boucle suivante:
for(var i=0; i<100; ++i){
let result = await some_slow_async_function();
do_something_with_result();
}
-
Ne
await
bloc de la boucle? Ou ne lei
continuer à être incrémenté toutawait
ing? -
Est de l'ordre de
do_something_with_result()
garanti séquentielle à l'égard dei
? Ou cela dépend-il de la façon dont rapidement laawait
ed fonction pour chaquei
?
- Avez-vous vraiment essayé?
- Oui, je suis un séquentielle résultat. Je n'étais pas sûr si c'était une coïncidence (la fonction async est effectivement rapide). Je n'étais pas sûr que ce soit de pousser tous les async des appels de fonction dans un tableau, puis faire un seul
await Promise.all(arr)
, ou si cette forme est correcte, et quelque chose d'autre était d'entraver l'souhaité l'asynchronicité. Si je fais un seulawait
pour le tout, alors que j'aurais du entrer dansPromise.map
afin de traiter chacun. Il me fait me remettre en question si.then
est mieux que async/await dans cette situation. - JS est déterministe. Soit la fonction est asynchrone ou il ne l'est pas, il ne dépend jamais d' "comment rapide" quelque chose est exécutée. Concernant
Promise.all
, qui fait quelque chose de différent - si c'est encore correct (ou même plus souhaitable) dépend de vos besoins. - Le temps d'une fonction à exécuter est non-déterministe, lorsqu'il fait un
async
opération qui consiste à une ressource externe, par exemple de base de données, e/s de fichier. - Oui, mais tant qu'il est asynchrone, il ne sera jamais à appeler ses rappels immédiatement, et toujours exécuter jusqu'à la fin de la synchronisation, le premier code.
Vous devez vous connecter pour publier un commentaire.
"Bloc" n'est pas le bon mot, mais oui, je ne continue pas à être incrémenté en attendant. Au lieu de l'exécution saute en arrière à l'endroit où le
async
fonction a été appelée, en fournissant une promesse comme valeur de retour, de continuer le reste du code qui suit, après l'appel de la fonction, jusqu'à ce que la pile du code a été vidé. Puis, quand l'attente est terminée, l'état de la fonction est restaurée, et l'exécution se poursuit à l'intérieur de cette fonction. Chaque fois que cette fonction retourne (complète), la promesse-qui était rentré plus tôt -- c'est résolu.L'ordre est garanti. Le code suivant de la
await
est aussi la garantie d'exécution qu'après l'appel de la pile est vide, c'est à dire au moins à compter de la prochaine microtask peut exécuter.Voir comment la sortie est dans cet extrait de code. Notez en particulier où il est dit "après l'appel de test":
JS:
async/await
était jusqu'à récemment mis en œuvre à l'aide de générateurs/yield
. Penser à elle de cette façon, tout devient plus clair. Je vais accepter cette réponse.then
comportement qu'avec des générateurs. Seul le "saut à l'endroit où il a été appelé" et "l'état de la fonction est restaurée" sontyield
..then
mais pas avecawait
, de penser à cela comme uneyield
résout à ma confusion.async
etawait
besoin d'un navigateur qui le supporte. Donc, pas d'Internet Explorer et pour Firefox ou Chrome: mise à jour dans leur dernière version.Comme @realbart dit, il ne bloque la boucle, qui sera ensuite de faire les appels séquentiels.
Si vous voulez déclencher une tonne de awaitable opérations et de gérer tous ensemble, vous pourriez faire quelque chose comme ceci:
promisesToAwait
tableau ne contiennent jamais de promesses.Vous pouvez tester async/await à l'intérieur d'une "BOUCLE", comme ceci:
JS:
Aucun Cas, la boucle n'est pas bloqué, voir exemple ci-dessous
JS:
async
fonctions de retour d'une Promesse, qui est un objet qui finira par "résoudre" à une valeur, ou "rejeter" avec une erreur. Leawait
mot-clé signifie d'attendre jusqu'à ce que cette valeur (ou une erreur) a été finalisée.Du point de vue de l'exécution de la fonction, il bloque en attente pour le résultat de la lenteur de la fonction async. Le moteur javascript, d'autre part, voit que cette fonction est bloquée en attente pour le résultat, donc il va aller vérifier la boucle d'événements (ie. de nouveaux clics de souris, ou les demandes de connexion, etc.) pour voir si il y a d'autres choses qu'il peut travailler sur jusqu'à ce que les résultats sont retournés.
Noter, cependant, que si la lenteur de la fonction async est lent parce que c'est le calcul de beaucoup de choses dans votre code javascript, le moteur javascript de ne pas avoir beaucoup de ressources pour faire d'autres choses (et en faisant d'autres trucs serait probablement la lenteur de la fonction async encore plus lente). D'où l'intérêt de async fonctions brillent vraiment, c'est pour les I/O des opérations intensives comme l'interrogation d'une base de données ou la transmission d'un fichier de grande taille où le moteur javascript est vraiment bien et en attente de quelque chose (ie. la base de données, système de fichiers, etc.).
Les deux morceaux de code sont fonctionnellement équivalentes:
et
Dans le deuxième exemple ci-dessus de la lenteur de la async fonction est appelée sans
await
mot-clé, de sorte qu'il va lancer l'exécution de la fonction et le retour d'une promesse. Ensuite, vous pouvez faire d'autres choses (si vous avez d'autres choses à faire). Puis leawait
mot-clé est utilisé pour bloquer jusqu'à ce que la promesse, en fait, "résout". Du point de vue de lafor
boucle, il sera exécuté synchrone.Donc:
oui, le
await
mot a pour effet de bloquer l'exécution de la fonction jusqu'à ce que la fonction async soit "résout" avec une valeur ou "rejette" avec une erreur, mais il ne bloque pas le moteur javascript, qui peut encore faire d'autres choses si elle a d'autres choses à faire en attendantoui, l'exécution de la boucle sera séquentielle
Il y a un super tutoriel à propos de tout cela à http://javascript.info/async.
ad 1. Oui. Pas de.
ad 2. Oui. No.
Preuve:
JS:
Pas, attendent de ne pas bloquer la boucle. Oui,
i
continue à être incrémenté en bouclant.Afin de
do_something_with_result()
est garanti de manière séquentielle mais pas en ce qui concernei
. Il dépend de la rapidité de l'attendu de la fonction s'exécute.Tous les appels à
some_slow_async_function()
sont groupées, c'est à dire, sido_something_with_result()
était unconsole
puis nous allons le voir imprimé le nombre de fois que la boucle s'exécute. Et puis, successivement, après cela, tous les attendent les appels seront exécutés.Pour mieux comprendre vous pouvez exécuter le code ci-dessous extrait de:
JS:
On peut clairement voir comment ligne
console.log('After', i, 'th API call');
est imprimé d'abord pour l'ensemble du tronçon de la boucle for et puis à la fin quand tout le code est exécuté, nous obtenons des résultats decallAPI()
.Donc, si les lignes après attendent étaient à la charge sur le résultat obtenu à partir de attendent des appels alors qu'ils ne fonctionnent pas comme prévu.
Pour conclure,
await
dansfor-loop
ne pas assurer le succès de l'opération sur le résultat obtenu à partir de attendent les appels qui peut prendre un certain temps pour terminer.Dans le nœud, si l'on utilise
neo-async
bibliothèque avecwaterfall
, on peut atteindre cet objectif.await callAPI()
retourner immédiatement. Si vous modifiez votrecallAPI()
de retour d'une promesse, alors cela va fonctionner.