¿Qué es el event loop y cómo maneja JavaScript el código asíncrono con un solo hilo?
Ver respuesta — intenta responderla en voz alta primero
El event loop es el mecanismo que le permite a JavaScript, que es de un solo hilo, manejar tareas asíncronas. Primero ejecuta todo el código síncrono (el call stack), luego las microtareas (promesas) y después las macrotareas (setTimeout, eventos), repitiendo el ciclo.
JavaScript tiene un solo hilo, así que no puede hacer dos cosas a la vez. El event loop coordina qué se ejecuta y cuándo, usando varias piezas:
- Call stack: la pila donde se ejecuta el código síncrono, un elemento a la vez.
- APIs del entorno (navegador o Node): manejan tareas que toman tiempo, como
setTimeouto peticiones. - Cola de microtareas: promesas resueltas (
.then,await). Estas tienen prioridad. - Cola de macrotareas: callbacks de
setTimeout,setInterval, eventos.
Esto es lo que hace el event loop: ejecuta todo el código síncrono; cuando el call stack está vacío, vacía la cola de microtareas por completo; luego toma una macrotarea, y vuelve a empezar.
El punto clave: las microtareas (promesas) se ejecutan antes que las macrotareas (setTimeout), incluso si el retraso del setTimeout es de 0 ms.
console.log("1 (síncrono)");
setTimeout(() => {
console.log("2 (macrotarea: setTimeout)");
}, 0);
Promise.resolve().then(() => {
console.log("3 (microtarea: promesa)");
});
console.log("4 (síncrono)");
// Salida:
// 1 (síncrono)
// 4 (síncrono)
// 3 (microtarea: promesa)
// 2 (macrotarea: setTimeout)
// Explicación del orden:
// - Primero el código síncrono: 1 y 4.
// - Luego se vacían las microtareas: 3 (la promesa).
// - Al final, las macrotareas: 2 (el setTimeout).
Pensar que setTimeout(fn, 0) se ejecuta antes que una promesa. No es así: las promesas son microtareas y tienen prioridad sobre las macrotareas como setTimeout. Otro error es creer que JavaScript es multihilo solo porque puede hacer cosas "al mismo tiempo"; en realidad delega en las APIs del entorno y coordina con el event loop.
"El event loop es lo que le permite a JavaScript, que es de un solo hilo, manejar código asíncrono. Primero ejecuta todo el código síncrono en el call stack. Cuando la pila está vacía, procesa la cola de microtareas, que son las promesas, y la vacía por completo. Luego toma una sola macrotarea, como un callback de
setTimeout, y repite el ciclo. Lo clave es que las promesas tienen prioridad sobresetTimeout, aunque el timeout sea de cero milisegundos."
Ordena la salida:
console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");
Ver respuesta
A, D, C, B. Primero lo síncrono (A, D), luego la microtarea de la promesa (C), y al final la macrotarea del setTimeout (B).