Worker threads
该 node:worker_threads
模块允许使用并行执行 JavaScript 的线程。要访问它,请执行以下操作:
const worker = require('node:worker_threads');
工作线程(线程)对于执行 CPU 密集型 JavaScript 操作非常有用。它们对 I/O 密集型工作没有多大帮助。Node.js内置异步 I/O 操作比 Workers 更高效。
与 或 cluster 不同 child_process
, worker_threads
可以共享内存。他们通过传输 ArrayBuffer
实例或共享 SharedArrayBuffer
实例来实现。
const { Worker, isMainThread, parentPort, workerData} = require('node:worker_threads')
if(isMainThread) {
module.exports = function parseJSAsync(script) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: script
})
worker.on('message', resolve)
worker.on('error', reject)
worker.on('exit', (code) => {
if(code !== 0) {
reject(new Error(`线程已退出 ${code}`))
}
})
})
}
} else {
const { parse } = require('一些js解析的库')
const script = workerData
parentPort.postMessage(parse(script))
}
worker.getEnvironmentData(key)
key
任何可用作键的任意、可克隆的 JavaScript 值。
在工作线程中, worker.getEnvironmentData()
返回传递给生成线程的数据克隆 worker.setEnvironmentData()
。每个新用户 Worker
都会自动接收自己的环境数据副本。
const {
Worker,
isMainThread,
setEnvironmentData,
getEnvironmentData,
} = require('node:worker_threads');
if (isMainThread) {
setEnvironmentData('Hello', 'World!');
const worker = new Worker(__filename);
} else {
console.log(getEnvironmentData('Hello')); // Prints 'World!'.
}
worker.isMainThread
如果 true
此代码未在 Worker
线程内运行。
const { Worker, isMainThread } = require('node:worker_threads');
if (isMainThread) {
// 这会重新加载 Worker 实例中的当前文件
new Worker(__filename);
} else {
console.log('Inside Worker!');
console.log(isMainThread); // Prints 'false'.
}
worker.parentPort
如果此线程是 Worker
,则允许 MessagePort
与父线程进行通信。使用 parentPort.postMessage()
发送的消息在父线程中使用 worker.on('message')
可用,从父线程发送的消息 using worker.postMessage()
在此线程中可用 parentPort.on('message')
。
const { Worker, isMainThread, parentPort } = require('node:worker_threads');
if (isMainThread) {
const worker = new Worker(__filename);
worker.once('message', (message) => {
console.log(message); // Prints 'Hello, world!'.
});
worker.postMessage('Hello, world!');
} else {
// When a message from the parent thread is received, send it back:
parentPort.once('message', (message) => {
parentPort.postMessage(message);
});
}
worker.receiveMessageOnPort(port)
接收来自给定 MessagePort
的 .如果没有可用的消息,则返回 undefined
,否则返回一个具有包含消息有效负载的单个 message
属性的对象,对应于 MessagePort
队列中最早的消息。
const { MessageChannel, receiveMessageOnPort } = require('node:worker_threads');
const { port1, port2 } = new MessageChannel();
port1.postMessage({ hello: 'world' });
console.log(receiveMessageOnPort(port2));
// Prints: { message: { hello: 'world' } }
console.log(receiveMessageOnPort(port2));
// Prints: undefined
使用此函数时,不会发出任何 'message'
事件,也不会调用 onmessage
侦听器。
worker.resourceLimits
在此 Worker 线程中提供一组 JS 引擎资源约束。如果 resourceLimits
将该选项传递给构造函数, Worker
则与其值匹配。
如果在主线程中使用此值,则其值为空对象。
worker.SHARE_ENV
一个特殊值,可以作为 Worker
构造函数 env
的选项传递,以指示当前线程和 Worker 线程应共享对同一组环境变量的读取和写入访问权限。
const { Worker, SHARE_ENV } = require('node:worker_threads');
new Worker('process.env.SET_IN_WORKER = "foo"', { eval: true, env: SHARE_ENV })
.on('exit', () => {
console.log(process.env.SET_IN_WORKER); // Prints 'foo'.
});
worker.threadId
当前线程的整数标识符。在相应的 worker
对象(如果有)上,它以 worker.threadId
.此值对于单个进程中的每个 Worker 实例都是唯一的。
const { Worker, isMainThread, parentPort } = require('node:worker_threads')
if(isMainThread) {
const worker = new Worker(__filename)
console.log( worker.threadId, '主线程ID');
worker.postMessage(worker.threadId)
} else {
parentPort.on('message', (data) => {
console.log(data, '子线程ID');
})
}
worker.workerData
一个任意 JavaScript 值,其中包含传递到此线程 Worker
构造函数的数据的克隆。
根据 HTML 结构化克隆算法,像使用 postMessage()
一样克隆数据。
const { Worker, isMainThread, workerData } = require('node:worker_threads');
if (isMainThread) {
const worker = new Worker(__filename, { workerData: 'Hello, world!' });
} else {
console.log(workerData); // Prints 'Hello, world!'.
}