Node.js berjalan di single thread dengan event loop. Untuk tugas CPU-intensive, gunakan Worker Threads agar tidak memblokir event loop.
Masalah single thread:
// BLOCKING — ini akan memblokir semua request lain!
app.get("/heavy", (req, res) => {
let result = 0;
for (let i = 0; i < 10_000_000_000; i++) {
result += i;
}
res.json({ result });
});
Solusi: Worker Threads
import { Worker, isMainThread, parentPort, workerData } from "worker_threads";
if (isMainThread) {
// Main thread — buat worker
const worker = new Worker("./heavy-task.js", {
workerData: { iterations: 1_000_000 },
});
worker.on("message", (result) => {
console.log("Hasil dari worker:", result);
});
worker.on("error", (err) => {
console.error("Worker error:", err);
});
worker.on("exit", (code) => {
console.log("Worker selesai dengan code:", code);
});
} else {
// Worker thread — terima data dan proses
const { iterations } = workerData;
let sum = 0;
for (let i = 0; i < iterations; i++) {
sum += i;
}
parentPort.postMessage(sum);
}
Komunikasi Worker ↔ Main Thread:
workerData— kirim data awal ke workerparentPort.postMessage()— worker kirim hasil ke mainworker.postMessage()— main kirim pesan ke workerparentPort.on("message")— worker terima pesan dari main
Worker Threads vs child_process:
| Worker Threads | child_process |
|---|---|
| Berbagi memori (SharedArrayBuffer) | Proses terpisah |
| Lebih ringan | Lebih berat |
| Untuk CPU-intensive JS | Untuk menjalankan command/script |
Kapan pakai Worker Threads:
- Kalkulasi matematika berat
- Image/video processing
- Parsing file besar (CSV, XML)
- Enkripsi/hashing
Kapan TIDAK perlu Worker Threads:
- I/O operations (sudah non-blocking)
- Database queries (driver sudah async)
- HTTP requests (sudah async)
Worker pool pattern:
import { Worker } from "worker_threads";
function runWorker(data) {
return new Promise((resolve, reject) => {
const worker = new Worker("./task.js", { workerData: data });
worker.on("message", resolve);
worker.on("error", reject);
});
}
app.get("/compute", async (req, res) => {
const result = await runWorker({ n: 1000000 });
res.json({ result });
});