Introducción: por qué tu sitio web "se ralentiza" y quién tiene la culpa
\n\nImagina un restaurante donde un solo camarero toma pedidos, sirve la comida, lava los platos y cuenta la caja al mismo tiempo. Caos, ¿verdad? Así funciona aproximadamente JavaScript de un solo hilo, si no gestionas las tareas correctamente. Cuando escribimos código que lo hace todo a la vez —carga datos, procesa clics, dibuja animaciones— el navegador se congela y el usuario ve una interfaz "pensativa".
\n\nHoy entenderemos cómo las colas de tareas en JavaScript ayudan a convertir este caos en un sistema ordenado. Aprenderás cómo el Event Loop distribuye las prioridades, en qué se diferencian las microtareas de las macrotareas, y cómo las tareas en segundo plano de JavaScript permiten no bloquear el hilo principal. Al final te esperan ejemplos prácticos que puedes implementar directamente en tu proyecto.
\n\nCómo funciona el Event Loop: el director de la orquesta de tareas
\n\nEn el centro de toda la asincronía está el Event Loop JavaScript. Es un mecanismo que gira infinitamente preguntando: "¿Hay algo que ejecutar? ¿Microtareas? ¿Renderizado?". Si alguna vez te has preguntado por qué setTimeout no se ejecuta de inmediato, mientras que Promise.then lo hace casi instantáneamente, la respuesta está aquí.
Pila de llamadas (Call Stack)
\nAquí es donde van las funciones para su ejecución inmediata. Mientras la pila esté ocupada, no ocurrirá nada más. Si tu función calcula un millón de números, el navegador se congelará porque la pila no se liberará.
\n\nCola de macrotareas (Macrotask Queue)
\nAquí van setTimeout, setInterval, eventos del DOM (clics, scroll), carga de recursos. El Event Loop toma una tarea de esta cola, la ejecuta, luego revisa las microtareas, luego renderiza la página — y vuelve a tomar la siguiente macrotarea.
Cola de microtareas (Microtask Queue)
\nEste es el reino de Promise, queueMicrotask, MutationObserver. Las microtareas tienen la máxima prioridad. En cuanto la pila se vacía, el Event Loop ejecuta TODAS las microtareas antes de pasar a la siguiente macrotarea. Por eso Promise.resolve().then() se ejecuta más rápido que setTimeout.
console.log('1');\n\nsetTimeout(() => {\n console.log('2');\n}, 0);\n\nPromise.resolve().then(() => {\n console.log('3');\n});\n\nconsole.log('4');\n\n// Salida: 1, 4, 3, 2\n\n\nEste ejemplo es un clásico. setTimeout (macrotarea) se pospone, incluso con retardo cero, mientras que Promise.then (microtarea) se ejecuta inmediatamente después del código síncrono. Entender este orden es clave para escribir código asíncrono predecible.
Tareas en segundo plano: cómo no bloquear la interfaz
\n\nAhora el problema principal: ¿qué hacer si necesitas ejecutar trabajo pesado (procesamiento de imágenes, cálculos complejos, análisis de datos)? Si lo ejecutas en el hilo principal, la interfaz se quedará congelada. La solución son las tareas en segundo plano de JavaScript.
\n\nWeb Workers — verdadero multiprocesamiento
\nLos Web Workers JS permiten ejecutar código en un hilo separado. No tienen acceso al DOM, pero pueden intercambiar mensajes con el hilo principal. Es la herramienta ideal para el procesamiento de colas JS en segundo plano.
\n\n// main.js\nconst worker = new Worker('worker.js');\n\nworker.postMessage({ data: [1, 2, 3, 4, 5, 6] });\n\nworker.onmessage = (event) => {\n console.log('Resultado del worker:', event.data);\n};\n\n// worker.js\nself.onmessage = (event) => {\n const numbers = event.data.data;\n // Trabajo pesado: filtrar números pares\n const result = numbers.filter(n => n % 2 === 0);\n self.postMessage(result);\n};\n\n\nObserva: el hilo principal no se bloquea. El usuario puede hacer clic, desplazarse, escribir texto — todo funcionará sin problemas mientras el worker calcula.
\n\n