Node.js 的 worker_threads
模块提供了在 Node.js 环境中创建和管理线程的能力。这使得可以在多个线程中并行执行 JavaScript 代码,从而提高应用程序的性能,尤其是对于 CPU 密集型任务。该模块是 Node.js 内置的,提供了一个与浏览器 Web Workers 类似的 API。
模块引入
在 Node.js 中,你可以通过 worker_threads
模块来使用线程功能:
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
或者使用 ES 模块语法:
import { Worker, isMainThread, parentPort, workerData } from 'worker_threads';
主要类和接口
Node.js worker_threads
模块主要包括以下几个类和接口:
1. Worker
Worker
类用于创建新的线程并在其中运行 JavaScript 代码。每个 Worker
实例代表一个独立的线程。
创建 Worker 示例:
const { Worker } = require('worker_threads');
// 创建一个新的 Worker 实例
const worker = new Worker('./worker.js', {
workerData: { foo: 'bar' }
});
// 监听 Worker 发送的消息
worker.on('message', (message) => {
console.log('Received message from worker:', message);
});
// 监听 Worker 错误
worker.on('error', (error) => {
console.error('Error from worker:', error);
});
// 监听 Worker 退出
worker.on('exit', (code) => {
if (code !== 0) {
console.error(`Worker stopped with exit code ${code}`);
}
});
构造函数:
-
new Worker(filename[, options])
filename
{string} 运行 Worker 的 JavaScript 文件路径。options
{Object} 配置选项。支持以下选项:workerData
{any} 传递给 Worker 线程的数据。stdout
{boolean} 默认为true
。如果为false
,则不在控制台输出 Worker 的stdout
。stderr
{boolean} 默认为true
。如果为false
,则不在控制台输出 Worker 的stderr
。execArgv
{string[]} 启动 Worker 时传递给 Node.js 的额外参数。
实例方法:
postMessage(value[, transferList])
: 向 Worker 发送消息。value
是要发送的消息,transferList
是一个可选的Array
,指定要转移的ArrayBuffer
和MessagePort
对象。terminate()
: 终止 Worker 线程并清理资源。返回一个Promise
,在 Worker 线程被终止时解析。
2. isMainThread
isMainThread
是一个布尔值,表示当前代码是否在主线程中。主线程是创建 Worker
实例的线程。
示例:
const { isMainThread } = require('worker_threads');
if (isMainThread) {
console.log('This is the main thread');
} else {
console.log('This is a worker thread');
}
3. parentPort
parentPort
是一个 MessagePort
对象,用于在 Worker 线程和主线程之间进行消息传递。它只能在 Worker 线程中访问。
示例:
const { parentPort } = require('worker_threads');
parentPort.postMessage('Hello from Worker');
4. workerData
workerData
是一个对象,包含传递给 Worker 线程的数据。在 Worker 线程中可以通过 worker_threads.workerData
访问这些数据。
示例:
const { workerData } = require('worker_threads');
console.log('Worker data:', workerData);
5. MessagePort
MessagePort
对象用于在不同线程之间传递消息。它提供了以下方法和事件:
方法:
postMessage(value[, transferList])
: 向对端发送消息。value
是要发送的消息,transferList
是一个可选的Array
,指定要转移的ArrayBuffer
和MessagePort
对象。
事件:
message
: 当接收到消息时触发。事件处理程序接收到一个MessageEvent
对象,其中包含接收到的消息。
示例:完整的 Worker 使用示例
worker.js
const { parentPort, workerData } = require('worker_threads');
// 处理传入的消息
parentPort.on('message', (message) => {
console.log('Received message from main thread:', message);
// 使用 workerData
console.log('Worker data:', workerData);
// 发送消息到主线程
parentPort.postMessage('Hello from worker');
});
main.js
const { Worker } = require('worker_threads');
// 创建一个新的 Worker 实例
const worker = new Worker('./worker.js', {
workerData: { foo: 'bar' }
});
// 监听 Worker 发送的消息
worker.on('message', (message) => {
console.log('Received message from worker:', message);
});
// 发送消息到 Worker
worker.postMessage('Hello from main thread');
// 处理 Worker 错误
worker.on('error', (error) => {
console.error('Error from worker:', error);
});
// 处理 Worker 退出
worker.on('exit', (code) => {
if (code !== 0) {
console.error(`Worker stopped with exit code ${code}`);
}
});
总结
Node.js 的 worker_threads
模块提供了强大的多线程功能,使得开发者可以在 Node.js 环境中并行执行 JavaScript 代码。通过 Worker
类、isMainThread
属性、parentPort
对象、workerData
和 MessagePort
对象,可以高效地创建和管理线程,实现并行处理,提升应用程序性能。这个模块为 CPU 密集型任务提供了有效的解决方案,适用于需要高性能计算的场景。