worker_threads
worker_threads descarga JavaScript pesado para la CPU a hilos paralelos sin generar un nuevo proceso del sistema operativo. Usa workerData, paso de mensajes y, opcionalmente, SharedArrayBuffer para el estado compartido.
Busca en todas las páginas de la documentación
worker_threads descarga JavaScript pesado para la CPU a hilos paralelos sin generar un nuevo proceso del sistema operativo. Usa workerData, paso de mensajes y, opcionalmente, SharedArrayBuffer para el estado compartido.
import { Worker } from 'node:worker_threads';
import { fileURLToPath } from 'node:url';
const worker = new Worker(fileURLToPath(new URL('./hash-worker.js', import.meta.url)), {
workerData: { input: 'payload' },
});
worker.on('message', (result) => console.log(result));Cuándo usarlo:
crypto// main.ts
import { Worker } from 'node:worker_threads';
import { cpus } from 'node:os';
import { fileURLToPath } from 'node:url';
const poolSize = Math.min(4, cpus().length);
const workers: Worker[] = [];
const queue: Array<{ data: number[]; resolve: (v: number) => void }> = [];
for (let i = 0; i < poolSize; i++) {
const w = new Worker(fileURLToPath(new URL('./sum-worker.js', import.meta.url)));
w.on('message', (sum: number) => {
const job = queue.shift();
job?.resolve(sum);
w.postMessage(job?.data ?? []);
});
workers.push(w);
}
export function sumInWorker(nums: number[]): Promise<number> {
return new Promise((resolve) => {
queue.push({ data: nums, resolve });
const idle = workers.find((w) => !w.threadId) ?? workers[0];
idle.postMessage(nums);
});
}// sum-worker.js
import { parentPort, workerData } from 'node:worker_threads';
parentPort?.on('message', (nums: number[]) => {
const sum = nums.reduce((a, b) => a + b, 0);
parentPort?.postMessage(sum);
});
if (workerData) {
parentPort?.postMessage('ready');
}Lo que esto demuestra:
postMessage usa el algoritmo de clonación estructurada, no para gráficos enormes en cada tickeval: true en producciónworkerData se clona una vez en la construcción.parentPort.postMessage es asíncrono entre hilos, copias serializadas.SharedArrayBuffer + Atomics para contadores sin bloqueo: avanzado, ten cuidado con las condiciones de carrera.| Factor | worker_threads | child_process |
|---|---|---|
| Inicio | Más rápido | Más lento |
| Aislamiento | Usuario de proceso compartido | Espacio de direcciones separado |
| Mejor para | JS de CPU | Binarios CLI |
| Impacto del fallo | Puede derribar el proceso | Hijo aislado |
import { isMainThread, parentPort, workerData } from 'node:worker_threads';
if (!isMainThread) {
const { job } = workerData as { job: string };
parentPort?.postMessage({ ok: true, job });
}error; adjunta un manejador o worker.on('error') bloquea la supervisión.| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
| child_process | Ejecutar binario no JS | CPU JS pura |
| cluster | Aceptar HTTP multi-núcleo | Un solo trabajo de cómputo pesado |
| WASM + worker | Cómputo en sandbox | Bucle JS simple |
| Servicio de trabajo externo | Flota de CPU en ráfaga | Baja latencia en la solicitud |
A menudo cpus().length - 1 o un fijo de 4; perfila; más que los núcleos puede ser perjudicial.
No, cada worker necesita sus propias conexiones o enviar mensajes al hilo principal para E/S.
ArrayBuffer puede transferir la propiedad sin copia a través del segundo argumento de postMessage.
La entrada del worker puede ser .js ESM; usa import.meta.url para resolver la ruta desde el principal.
No por defecto; descarga manualmente o usa BullMQ para CPU en segundo plano.
node --inspect con --inspect-port por worker; o registra desde el worker al principal.
Sí, una tarea larga bloquea ese worker, no el hilo principal; el tamaño del pool importa.
piscina: una abstracción popular de pool de workers en npm.
Sí, los workers ayudan a la CPU; el hilo principal aún maneja toda la E/S HTTP.
Requiere aislamiento de origen cruzado en navegadores; Node tiene menos restricciones, pero las condiciones de carrera persisten.
await worker.terminate(): forzado; prefiere mensajes de cancelación cooperativos.
El pool de libuv maneja algo de E/S/cripto; workers para bucles de CPU de JS que libuv no puede arreglar.
Versiones de la pila: Esta página fue escrita para Node.js 24.18.0 (LTS activa), npm 10+, TypeScript 5.6+, Express 5, Fastify 5 y NestJS 11.
Revisado por Chris St. John·Última actualización: 16 jul 2026