infinito - En JavaScript, ¿usar `await` dentro de un bucle bloquea el bucle?
ciclo while en javascript (4)
- ¿
await
bloquear el ciclo? ¿O sigo incrementándose mientrasawait
?
"Bloquear" no es la palabra correcta, pero sí, no continúo incrementándose mientras espero. En su lugar, la ejecución vuelve al punto donde se llamó a la función async
, proporcionando una promesa como valor de retorno, continuando el resto del código que sigue después de la llamada de función, hasta que se haya vaciado la pila de códigos. Luego, cuando finaliza la espera, se restablece el estado de la función y la ejecución continúa dentro de esa función. Siempre que esa función retorna (completa), se resuelve la promesa correspondiente, que se devolvió anteriormente.
- ¿
do_something_with_result()
garantiza el orden dedo_something_with_result()
secuencial con respecto ai
? ¿O depende de cuán rápido la función deawait
es para cadai
?
La orden está garantizada También se garantiza que el código que sigue a await
se ejecutará solo después de que se haya vaciado la pila de llamadas, es decir, al menos en o después de que se pueda ejecutar la siguiente microtask.
Vea cómo es el resultado en este fragmento. Tenga en cuenta especialmente donde dice "después de la prueba de llamada":
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'');
Tome el siguiente ciclo:
for(var i=0; i<100; ++i){
let result = await some_slow_async_function();
do_something_with_result();
}
¿
await
bloquear el ciclo? ¿O sigo incrementándose mientrasawait
?¿
do_something_with_result()
garantiza el orden dedo_something_with_result()
secuencial con respecto ai
? ¿O depende de cuán rápido la función deawait
es para cadai
?
Como dice @realbart, bloquea el ciclo, lo que hará que las llamadas sean secuenciales.
Si desea activar una tonelada de operaciones esperables y luego manejarlas todas juntas, podría hacer algo como esto:
const promisesToAwait = [];
for (let i = 0; i < 100; i++) {
promisesToAwait.push(fetchDataForId(i));
}
const responses = await Promise.all(promisesToAwait);
Sí, aguarde a bloquear el ciclo, por lo que la orden está garantizada. No bloquea más ejecución de scripts.
puedes probar esto:
async function main() {
await ping();
}
async function ping() {
for (var i = 0; i < 10; i++) {
await delay(3000);
console.log("ping" + i);
}
}
function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
window.setInterval(() => console.log(''interval...''), 1000); // just keeps on going
main();
No pude hacer que esto funcione en ningún navegador, pero puede verlo en el trabajo como mecanografiado:
Puede probar async / await dentro de un "FOR LOOP" como este:
(async () => {
for (let i = 0; i < 100; i++) {
await delay();
console.log(i);
}
})();
function delay() {
return new Promise((resolve, reject) => {
setTimeout(resolve, 100);
});
}