En JavaScript, l'utilisation de ' await` dans une boucle bloque-t-elle la boucle?
Prenez la boucle suivante:
for(var i=0; i<100; ++i){
let result = await some_slow_async_function();
do_something_with_result();
}
await
bloque-t-il la boucle? Ou lei
continue-t-il à être incrémenté pendant queawait
ing?L'ordre de
do_something_with_result()
est-il garanti séquentiel par rapport ài
? Ou dépend-il de la vitesse de la fonctionawait
ed pour chaquei
?
3 réponses
await
bloque-t-il la boucle? Ou lei
continue-t-il à être incrémenté pendant queawait
ing?
"Bloc" n'est pas le bon mot, mais oui, , je ne pas continuer à être incrémenté en attendant. Au lieu de cela, l'exécution revient à l'endroit où la fonction async
a été appelée, fournissant une promesse comme valeur de retour, continuant le reste du code qui suit après l'appel de la fonction, jusqu'à ce que la pile de code ait été vidée. Puis quand l'attente est terminée, l'état de la fonction est restauré et l'exécution se poursuit dans cette fonction. Chaque fois que cette fonction retourne (complète), la promesse correspondante-qui a été renvoyée plus tôt-est résolue.
- L'ordre de
do_something_with_result()
est-il garanti séquentiel par rapport ài
? Ou dépend-il de la vitesse de la fonctionawait
ed pour chaquei
?
L'ordre est garanti. Le code suivant le await
est également garanti pour exécuter seulement après le la pile d'appels a été vidée, c'est-à-dire au moins sur ou après l'exécution de la prochaine microtask.
Voir comment la sortie est dans cet extrait. Notez surtout où il est dit "Après avoir appelé test":
async function test() {
for (let i = 0; i < 2; i++) {
console.log('Before await for ', i);
let result = await Promise.resolve(i);
console.log('After await. Value is ', result);
}
}
test().then(_ => console.log('After test() resolved'));
console.log('After calling test');
Comme le dit @realbart, il bloque la boucle, ce qui rendra les appels séquentiels.
Si vous voulez déclencher une tonne d'opérations attendues et les gérer toutes ensemble, vous pouvez faire quelque chose comme ceci:
const promisesToAwait = [];
for (let i = 0; i < 100; i++) {
promisesToAwait.push(fetchDataForId(i));
}
const responses = await Promise.all(promisesToAwait);
Vous pouvez tester async / await dans une boucle " FOR " comme ceci:
(async () => {
for (let i = 0; i < 100; i++) {
await delay();
console.log(i);
}
})();
function delay() {
return new Promise((resolve, reject) => {
setTimeout(resolve, 100);
});
}