← Назад к вопросам
Что такое Worker Threads в Node.js?
1.2 Junior🔥 231 комментариев
#Node.js и JavaScript
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Worker Threads — это встроенная в Node.js функция для запуска JavaScript кода в отдельных потоках. Это позволяет выполнять CPU-интенсивные операции без блокировки основного потока Event Loop.
Проблема, которую решают Worker Threads
Node.js однопоточный — весь код выполняется в одном потоке. Если выполнить CPU-интенсивную операцию, это заблокирует весь сервер:
// Плохо — блокирует Event Loop
const crypto = require('crypto');
app.get('/hash', (req, res) => {
const hash = crypto.pbkdf2Sync('password', 'salt', 100000, 64, 'sha512');
res.send(hash);
});
// Если запустить 10 запросов одновременно, они будут обработаны по очереди
// Каждый запрос ждёт 1 секунду = 10 запросов * 1 сек = 10 секунд для всех!
Worker Threads решают эту проблему:
const { Worker } = require('worker_threads');
const path = require('path');
app.get('/hash', (req, res) => {
const worker = new Worker(path.join(__dirname, 'hash-worker.js'));
worker.on('message', (hash) => {
res.send(hash);
});
worker.on('error', (err) => {
res.status(500).send(err.message);
});
worker.on('exit', (code) => {
if (code !== 0) res.status(500).send('Worker stopped');
});
});
// hash-worker.js
const crypto = require('crypto');
const { parentPort } = require('worker_threads');
const hash = crypto.pbkdf2Sync('password', 'salt', 100000, 64, 'sha512');
parentPort.postMessage(hash);
Основные концепции
Worker Thread запускается в отдельном потоке:
- Не блокирует Event Loop
- Не делится памятью (отдельный V8 instance)
- Может быть переиспользован для нескольких задач
const { Worker } = require('worker_threads');
const worker = new Worker('./worker.js');
// Отправить сообщение worker'у
worker.postMessage({ data: 'hello' });
// Получить сообщение от worker'а
worker.on('message', (msg) => {
console.log('Received:', msg);
});
// Завершить worker
worker.terminate();
Пример: Worker Pool
const { Worker } = require('worker_threads');
const path = require('path');
class WorkerPool {
constructor(workerScript, poolSize = 4) {
this.workers = [];
this.taskQueue = [];
this.poolSize = poolSize;
for (let i = 0; i < poolSize; i++) {
const worker = new Worker(workerScript);
worker.busy = false;
worker.on('message', () => {
worker.busy = false;
this.processQueue();
});
this.workers.push(worker);
}
}
execute(data) {
return new Promise((resolve, reject) => {
const task = { data, resolve, reject };
const freeWorker = this.workers.find(w => !w.busy);
if (freeWorker) {
this.runTask(freeWorker, task);
} else {
this.taskQueue.push(task);
}
});
}
runTask(worker, task) {
worker.busy = true;
worker.once('message', (result) => {
task.resolve(result);
});
worker.once('error', (err) => {
task.reject(err);
});
worker.postMessage(task.data);
}
processQueue() {
if (this.taskQueue.length === 0) return;
const freeWorker = this.workers.find(w => !w.busy);
if (freeWorker) {
const task = this.taskQueue.shift();
this.runTask(freeWorker, task);
}
}
}
const pool = new WorkerPool(path.join(__dirname, 'heavy-task.js'), 4);
for (let i = 0; i < 10; i++) {
pool.execute({ n: 1000000 })
.then(result => console.log('Result:', result))
.catch(err => console.error('Error:', err));
}
heavy-task.js (Worker Script)
const { parentPort } = require('worker_threads');
parentPort.on('message', (data) => {
// CPU-интенсивная работа
let sum = 0;
for (let i = 0; i < data.n; i++) {
sum += Math.sqrt(i);
}
parentPort.postMessage(sum);
});
Когда использовать Worker Threads
- Криптография — хеширование паролей, подписание JWT
- Обработка изображений — изменение размера, конвертация форматов
- Математические расчёты — сложные вычисления
- Сжатие данных — gzip, brotli
- Парсинг больших файлов — JSON, CSV, XML
- Machine Learning — инференс моделей
Не использовать для:
- I/O операций (это не помогает)
- Простых синхронных операций (overhead не стоит)
- Сетевых запросов (используй async/await)
Worker Threads vs Cluster vs Process
Worker Threads:
- Лёгкие потоки внутри одного процесса
- Общая память (с ограничениями)
- Для CPU-интенсивных задач
- Маленький overhead
Cluster:
- Отдельные Node.js процессы
- Полная изоляция
- Для балансировки нагрузки
- Требует больше памяти
Child Process:
- Любые программы (не только Node.js)
- Для запуска скриптов на других языках
Пример: Хеширование пароля
const { Worker } = require('worker_threads');
app.post('/register', async (req, res) => {
const worker = new Worker(`
const { parentPort } = require('worker_threads');
const crypto = require('crypto');
parentPort.on('message', (password) => {
const hash = crypto.pbkdf2Sync(password, 'salt', 100000, 64, 'sha512');
parentPort.postMessage(hash.toString('hex'));
});
`, { eval: true });
worker.postMessage(req.body.password);
worker.on('message', async (hash) => {
await User.create({ email: req.body.email, password: hash });
res.send('Registered');
});
});
Worker Threads — это мощный инструмент для оптимизации производительности Node.js приложений при работе с CPU-интенсивными операциями.