Concurrencia y multiprocesamiento en JavaScript: Guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Concurrencia y subprocesos múltiples en JavaScript: cómo hacer que el código funcione más rápido



JavaScript históricamente ha sido un lenguaje de un solo subproceso, pero esto no significa que no pueda manejar múltiples tareas simultáneamente. En el Node.js moderno y los navegadores, existen mecanismos potentes para trabajar con concurrencia y subprocesos múltiples. Comprender estos conceptos es críticamente importante para crear aplicaciones de servidor y cliente de alto rendimiento.



En este artículo, analizaremos en qué se diferencia la concurrencia del paralelismo, cómo funciona el Event Loop, cuándo usar Worker Threads y Web Workers, y también veremos ejemplos prácticos en Node.js.



1. Event Loop y entrada/salida no bloqueante



La base de la concurrencia en JavaScript es el Event Loop (bucle de eventos). Este es un mecanismo que permite ejecutar operaciones asíncronas (por ejemplo, lectura de archivos, consultas a bases de datos) sin bloquear el subproceso principal.



Imagínese una cola: el Event Loop toma una tarea de la cola (call stack), la ejecuta, y si encuentra una operación asíncrona (por ejemplo, setTimeout o fetch), la pasa a la Web API (en el navegador) o a libuv (en Node.js). Una vez que la operación se completa, su callback se coloca en la cola de tareas (task queue). El Event Loop verifica constantemente si la pila está vacía y, si lo está, toma la siguiente tarea de la cola.



Ejemplo de código asíncrono:



const fs = require('fs');

console.log('Inicio');

fs.readFile('example.txt', 'utf8', (err, data) => { if (err) throw err; console.log('Archivo leído:', data);});

console.log('Fin');

// Salida:// Inicio// Fin// Archivo leído: ...


Tenga en cuenta: console.log('Fin') se ejecuta antes de la lectura del archivo. Esto es la entrada/salida no bloqueante: el subproceso principal no espera a que la operación termine, sino que continúa su ejecución.



2. Web Workers y Worker Threads: verdadera ejecución multihilo



Aunque el Event Loop maneja muy bien las operaciones de E/S, no ayuda cuando se ejecutan cálculos "pesados" (procesamiento de imágenes, criptografía, ordenamientos complejos). Si se ejecuta dicho código en el subproceso principal, toda la interfaz (o el servidor) se "congelará" hasta que finalicen los cálculos.



Para resolver este problema, existen Web Workers (en el navegador) y Worker Threads (en Node.js). Permiten ejecutar código JavaScript en subprocesos separados del sistema operativo.



Ejemplo con Worker Threads en Node.js



Creemos un archivo worker.js:



const { parentPort } = require('worker_threads');

// Tarea pesada: calcular la suma de númeroslet sum = 0;for (let i = 0; i < 1e9; i++) { sum += i;}

// Enviamos el resultado de vuelta al subproceso principalparentPort.postMessage(sum);


Archivo principal main.js:



const { Worker } = require('worker_threads');

console.log('Subproceso principal: iniciando worker');

const worker = new Worker('./worker.js');

worker.on('message', (result) => { console.log('Resultado del worker:', result);});

worker.on('error', (err) => { console.error('Error del worker:', err);});

worker.on('exit', (code) => { if (code !== 0) { console.error(`Worker finalizado con código ${code}`); }});

console.log('Subproceso principal: continuando trabajo...');

// Salida:// Subproceso principal: iniciando worker// Subproceso principal: continuando trabajo...// Resultado del worker: 499999999500000000


Como puede ver, el subproceso principal no se bloquea, mientras que el worker ejecuta los cálculos en segundo plano. Esto es verdadera ejecución multihilo.



3. Async/Await y Promise: gestión de la concurrencia



JavaScript moderno ofrece formas elegantes de trabajar con código asíncrono: async/await y Promise. No crean nuevos subprocesos, p

Blogs

Book Recommendations