Microtareas vs Macrotareas: Radiografía extrema del Event Loop y la pila de ejecución.
📚 Contenido de la guía ⌃
Tu app "se cuelga"… pero no está colgada. En realidad, está obedeciendo una ley invisible: primero se vacía la pila, luego se drenan las microtareas, y solo después el mundo respira otro tick.
Este post no te da trucos baratos para pasar entrevistas: te da rayos X. Vas a ver la pila, las colas y el loop como si tuvieras un monitor cardíaco del runtime directamente en tu pantalla. ¿Estás listo para ver el orden exacto en el que ocurren las cosas?
1) El mito: “JS es single-thread, entonces todo es lineal”
Es el primer dogma que aprendemos: "JavaScript tiene un solo hilo". Y aunque es una afirmación técnicamente correcta, nuestra mente suele malinterpretarla, asumiendo que el código se ejecuta de manera estrictamente lineal, bloqueando el resto del mundo hasta que cada línea termina de procesarse.
Si este fuera el caso, un simple setTimeout de 5 segundos o una petición fetch pesada congelarían toda tu interfaz y el navegador te mostraría la temida alerta de "La página no responde". Afortunadamente, JavaScript no trabaja solo.
🧠 Qué significa DE VERDAD ser "Single-Thread"
Significa que el motor de JavaScript (como V8 en Chrome o Node.js) tiene una única Pila de Ejecución (Call Stack). Solo un bloque de código puede ser interpretado y procesado por el lenguaje en un instante preciso. No hay paralelismo real de ejecución dentro de tu código JS.
🚫 Qué NO significa (El entorno al rescate)
Que JS sea de un solo hilo no significa que tu navegador (o tu servidor) lo sea. Cuando solicitas operaciones asíncronas pesadas (I/O, temporizadores, renderizado de DOM), JS le "delega" ese trabajo a las Web APIs (en el browser) o a libuv (en Node). Esos componentes externos sí trabajan en segundo plano. Cuando terminan, simplemente avisan de regreso: "¡Hey, ya tengo los datos, ponme en la cola!".
2) Definición quirúrgica: Macrotareas vs Microtareas
Ya tenemos la radiografía lista. Ahora pongamos la lupa en las dos colas que viste en el diagrama anterior. Aquí es donde el 90% de los desarrolladores se confunden, asumiendo que todo lo "asíncrono" va exactamente al mismo saco de espera.
La realidad es que el Event Loop es un orquestador estricto: maneja una cola general (Macrotareas) y una cola VIP de urgencia (Microtareas). Entender cómo el motor intercala ambas colas es el único secreto real para predecir el comportamiento de tu código.
La Regla de Oro 🏆
"Cuando la pila queda vacía, el runtime drena TODAS las microtareas antes de pasar al siguiente tick (macrotarea)."
📦 Macrotareas: El "latido" del loop
Imagina las macrotareas como el ritmo base de un metrónomo. Cada vez que el Event Loop da una vuelta completa (lo que llamamos un tick), toma solo una macrotarea de la Task Queue, la pasa a la Pila de Ejecución y la corre hasta que termina.
- Sospechosos habituales:
setTimeout,setInterval, eventos del DOM (clicks, teclado), callbacks de red y operaciones de I/O en Node. - Regla de convivencia: Al ejecutar solo una a la vez, el Event Loop le da espacio al navegador para repintar la pantalla entre una macrotarea y otra.
⚡ Microtareas: El "barrido inmediato"
Las microtareas son la máxima prioridad asíncrona. Una vez que el código síncrono actual termina (y la pila queda vacía), el Event Loop mira inmediatamente a la Microtask Queue. Si hay algo ahí, lo ejecuta todo de golpe hasta vaciar la cola por completo, antes de permitir que se ejecute la siguiente macrotarea o se actualice la pantalla.
- Sospechosos habituales:
Promise.then(),Promise.catch(),queueMicrotask()yMutationObserver. - Peligro latente: Si una microtarea encola infinitamente a otra microtarea, atraparás al Event Loop en un ciclo de "barrido inmediato" infinito, congelando por completo tu aplicación (el navegador ni siquiera podrá hacer scroll).
3) El caso clínico: predice el orden (y gana)
La teoría suena fantástica, pero la única forma de saber si realmente entendiste el Event Loop es prediciendo el comportamiento de un motor de JavaScript real.
A continuación, tienes un snippet de código. Usa la radiografía mental que acabamos de construir: identifica qué va a la pila síncrona, qué va a la cola de macrotareas y qué va a la cola VIP de microtareas.
console.log("A");
setTimeout(() => console.log("B (timeout)"), 0);
Promise.resolve()
.then(() => console.log("C (promise then)"))
.then(() => console.log("D (promise then 2)"));
queueMicrotask(() => console.log("E (queueMicrotask)"));
console.log("F");
Comentarios y Valoraciones
No hay comentarios aún. ¡Sé el primero en opinar!