Skip to content

worker_threads

worker_threads เป็นโมดูลในตัวของ Node.js ที่ช่วยให้สามารถรัน JavaScript ในเธรดแบบขนาน (parallel threads) ได้ เหมาะสำหรับงานที่ใช้ CPU หนักๆ เพื่อไม่ให้บล็อก Event Loop หลัก

import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';

APIคำอธิบายลักษณะคำอธิบายเพิ่มเติม
Workerคลาสสำหรับสร้างและจัดการ Worker ThreadClassใช้สร้างเธรดใหม่เพื่อรันงานแบบขนาน
isMainThreadตรวจสอบว่าโค้ดกำลังรันในเธรดหลักหรือไม่Booleanคืนค่า true ถ้าเป็นเธรดหลัก, false ถ้าเป็น Worker Thread
parentPortช่องทางการสื่อสารกับเธรดหลักMessagePortใช้ใน Worker Thread เพื่อส่ง/รับข้อมูลจากเธรดหลัก
workerDataข้อมูลที่ส่งจากเธรดหลักไปยัง WorkerAnyใช้ส่งข้อมูลเริ่มต้นให้ Worker Thread ไม่ต้องใช้ parentPort
MessageChannelช่องทางการสื่อสารระหว่าง Worker ThreadsClassสร้างคู่ MessagePort สำหรับสื่อสารโดยตรงระหว่างเธรด
MessagePortปลายทางสำหรับส่ง/รับข้อความระหว่างเธรดClassใช้รับฟังและส่งข้อความผ่าน event 'message'
threadIdID ของเธรดปัจจุบันIntegerค่าเฉพาะสำหรับแต่ละเธรด
SHARE_ENVตัวแปรสำหรับแชร์ env ระหว่างเธรดSymbolใช้กับ Worker constructor เพื่อแชร์ process.env กับ Worker Thread
worker.resourceLimitsตรวจสอบขีดจำกัดทรัพยากรของ WorkerObjectแสดงค่าขีดจำกัดหน่วยความจำและ CPU
worker.performanceข้อมูลประสิทธิภาพของ WorkerObjectมีเมธอดสำหรับวัดประสิทธิภาพการทำงานของ Worker Thread

ตัวอย่าง

การสร้าง Worker เบื้องต้น

js
// main.js (เธรดหลัก)
import { isMainThread, Worker } from "worker_threads";

if (isMainThread) {
  // สร้าง Worker Thread
  const worker = new Worker("./worker.js", {
    workerData: { initialData: "Hello from Main Thread" },
  });

  // รับข้อมูลจาก Worker
  worker.on("message", (msg) => {
    console.log("จาก Worker:", msg);
  });

  // จัดการเมื่อ Worker ส่งข้อผิดพลาด
  worker.on("error", (err) => {
    console.error("Worker เกิดข้อผิดพลาด:", err);
  });

  // จัดการเมื่อ Worker ปิดตัวเอง
  worker.on("exit", (code) => {
    console.log("Worker ปิดตัวเองด้วยรหัส:", code);
  });
}

// worker.js (Worker Thread)
import { parentPort, workerData } from "worker_threads";

// รับข้อมูลเริ่มต้นจากเธรดหลัก
console.log("ข้อมูลเริ่มต้น:", workerData.initialData);

// ส่งข้อมูลกลับไปยังเธรดหลัก
parentPort.postMessage({ result: "Hello from Worker Thread" });

การส่งข้อมูลระหว่าง threads

js
// main.js
import { Worker } from "worker_threads";

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

// ส่งข้อมูลไปยัง Worker
worker.postMessage({ task: "process_data", data: [1, 2, 3, 4, 5] });

// worker.js
import { parentPort } from "worker_threads";

parentPort.on("message", (msg) => {
  if (msg.task === "process_data") {
    const result = msg.data.map(x => x * 2);
    parentPort.postMessage({ result });
  }
});

การใช้ MessageChannel

js
import { MessageChannel, Worker } from "worker_threads";

const { port1, port2 } = new MessageChannel();

const worker = new Worker("./worker.js", {
  workerData: { port: port2 },
  transferList: [port2],
});

port1.on("message", (msg) => {
  console.log("ได้รับจาก Worker:", msg);
});

port1.postMessage("Hello from Main Thread");

การจัดการ Worker Pool

js
import { Worker } from "worker_threads";

class WorkerPool {
  constructor(numThreads, workerPath) {
    this.workers = [];
    for (let i = 0; i < numThreads; i++) {
      const worker = new Worker(workerPath);
      this.workers.push(worker);
    }
    this.taskQueue = [];
  }

  execute(task) {
    return new Promise((resolve) => {
      const worker = this.workers.pop();
      if (worker) {
        worker.once("message", (result) => {
          this.workers.push(worker);
          resolve(result);
        });
        worker.postMessage(task);
      } else {
        this.taskQueue.push({ task, resolve });
      }
    });
  }
}

// ใช้งาน
const pool = new WorkerPool(4, "./worker.js");
pool.execute({ data: "example" }).then(console.log);