Ejecuto este código en Nodejs y espero que haya un error, ¡pero funcionó! Si configuro 2500 ms para setTimeout , aparece un error y es normal. ¿Hay alguien aquí que me lo explique? ¿Y por qué veo el registro de IIFE primero?
Ejecuté este código en el navegador y obtuve el error que esperaba.
const data = [{}] const myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve([1,2,3,4]); }, 3000); }); console.log('hiiii'); setTimeout(() => { data[0].map(e => console.log('to ',e)) }, 2999); (async() => { data[0] = await myPromise data[0].map(e => console.log('iife ',e)) } )() console.log('byeeeee')El siguiente código es lo que veo en mi consola
hiiii byeeeee iife 1 iife 2 iife 3 iife 4 to 1 to 2 to 3 to 4Si la línea 10 se ejecuta al menos 1 ms después de la línea 2, su devolución de llamada se pondrá en cola para ejecutarse después de la devolución de llamada con resolve() (y, por lo tanto, después del registro "iife", que ocurre después de resolve() ).
La solución es mover el segundo setTimeout() antes del primero, para asegurarse de que sus devoluciones de llamada se pongan en cola en el orden esperado. Entonces, por ejemplo, este código:
const data = [[99]]; setTimeout(() => { data[0].forEach(e => console.log('to ',e)) }, 2999); const myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve([1,2,3,4]); }, 3000); }); console.log('hiiii'); (async() => { data[0] = await myPromise data[0].forEach(e => console.log('iife ',e)) } )(); console.log('byeeeee');produce de forma fiable este resultado:
hiiii byeeeee to 99 iife 1 iife 2 iife 3 iife 4La lógica del bucle de eventos es tal que llamar a setTimeout pondrá en cola su devolución de llamada para que se pueda ejecutar x milisegundos después de la hora actual. Una vez que pasa esa cantidad de tiempo, entonces tiene que esperar a que finalice cualquier tarea que se esté ejecutando actualmente, y luego esperar a cualquier otra tarea que se haya puesto en cola antes de que pueda ejecutarse.
No estoy seguro de lo que está tratando de hacer, pero nunca obtendrá la línea "to 1" antes de la línea "iife 4", porque todo, desde la configuración de datos [0] hasta el registro de "iife 4" sucede dentro de un solo , trozo de código síncrono.