Skip to main content
Практика завдань

Що таке worker threads у Node.js?

Потоки Робітників у Node.js

Потоки Робітників (впроваджені в Node.js 10, стабільні в 12) дозволяють виконувати JavaScript у паралельних потоках в межах одного процесу. На відміну від модуля Cluster (який створює окремі процеси), потоки робітників ділять пам'ять і призначені для обчислювальних задач.


Коли Використовувати Потоки Робітників

Сценарій використанняРекомендовано
Операції вводу/виводу (файл, мережа)❌ Цикл подій справляється з цим добре
Важкі обчислення (МЛ, хешування, парсинг)✅ Потоки Робітників
Паралельні HTTP сервери❌ Використовуйте Cluster
Обробка зображень/відео✅ Потоки Робітників
Блокуючі синхронні бібліотеки✅ Потоки Робітників

Основний Приклад

js
// worker.js const { workerData, parentPort } = require('worker_threads'); function heavyComputation(n) { let result = 0; for (let i = 0; i < n; i++) result += Math.sqrt(i); return result; } const result = heavyComputation(workerData.n); parentPort.postMessage(result); // відправити результат назад
js
// main.js const { Worker } = require('worker_threads'); function runWorker(workerData) { return new Promise((resolve, reject) => { const worker = new Worker('./worker.js', { workerData }); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) reject(new Error(`Потік робітника завершився з кодом ${code}`)); }); }); } // Основний потік НЕ заблокований! runWorker({ n: 1e9 }).then(result => { console.log('Результат:', result); }); console.log('Основний потік продовжує виконання...');

Спільна Пам'ять з SharedArrayBuffer

js
// main.js const { Worker } = require('worker_threads'); const sharedBuffer = new SharedArrayBuffer(4); // 4 байти const sharedArray = new Int32Array(sharedBuffer); sharedArray[0] = 0; const worker = new Worker(` const { workerData } = require('worker_threads'); const shared = new Int32Array(workerData.sharedBuffer); shared[0] = 42; // запис у спільну пам'ять `, { eval: true, workerData: { sharedBuffer } }); worker.on('exit', () => { console.log('Спільне значення:', sharedArray[0]); // 42 });

Шаблон Пулу Потоків Робітників

Для виробничого використання створіть пул для повторного використання робітників:

js
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads'); const os = require('os'); class WorkerPool { constructor(workerFile, size = os.cpus().length) { this.workers = Array.from({ length: size }, () => ({ worker: new Worker(workerFile), busy: false })); this.queue = []; } run(data) { return new Promise((resolve, reject) => { const free = this.workers.find(w => !w.busy); if (free) { this._execute(free, data, resolve, reject); } else { this.queue.push({ data, resolve, reject }); } }); } _execute(entry, data, resolve, reject) { entry.busy = true; entry.worker.postMessage(data); entry.worker.once('message', result => { entry.busy = false; resolve(result); if (this.queue.length > 0) { const next = this.queue.shift(); this._execute(entry, next.data, next.resolve, next.reject); } }); entry.worker.once('error', reject); } }

Потоки Робітників vs Cluster

Потоки РобітниківCluster
ПроцесОдин і той же процесОкремі процеси
Пам'ятьМожуть ділити (SharedArrayBuffer)Окрема пам'ять
КомунікаціяШвидка (MessagePort)Повільніша (IPC)
Найкраще дляОбчислень ЦПМасштабування мережі
ІзоляціяНижчаВища (аварія процесу)

Резюме

Потоки Робітників вирішують найбільше обмеження Node.js: обчислювальні задачі, які блокують цикл подій. Використовуйте їх для важких обчислень — але для більшості задач, пов'язаних з вводу/виводу, цикл подій справляється з паралелізмом ідеально без потоків.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань