类:Worker
【Class: Worker】
Worker 类表示一个独立的 JavaScript 执行线程。大多数 Node.js API 在其中都是可用的。
【The Worker class represents an independent JavaScript execution thread.
Most Node.js APIs are available inside of it.】
工作线程环境中的显着差异是:
【Notable differences inside a Worker environment are:】
process.stdin、process.stdout和process.stderr流可能会被父线程重定向。require('node:worker_threads').isMainThread属性被设置为false。require('node:worker_threads').parentPort消息端口可用。process.exit()不会停止整个程序,只会停止单个线程,而且process.abort()不可用。- 设置组或用户 ID 的
process.chdir()和process方法不可用。 process.env是父线程环境变量的副本,除非另有说明。对其中一个副本的更改在其他线程中不可见,也不会被本地插件看到(除非将worker.SHARE_ENV作为env选项传递给Worker构造函数)。在 Windows 上,与主线程不同,环境变量的副本以区分大小写的方式操作。process.title无法修改。- 信号不会通过
process.on('...')传输。 - 由于调用了
worker.terminate(),执行可能在任何时候停止。 - 父进程的 IPC 通道无法访问。
- 不支持
trace_events模块。 - 本地插件只有在满足 某些条件 的情况下才能从多个线程加载。
在另一个 Worker 内部创建 Worker 实例是可能的。
【Creating Worker instances inside of other Workers is possible.】
像 网页工作者 和 node:cluster 模块 一样,通过线程间消息传递可以实现双向通信。在内部,Worker 内置了一对 MessagePort,它们在 Worker 创建时已经相互关联。虽然父线程一侧的 MessagePort 对象不会直接暴露,但其功能通过 worker.postMessage() 和 Worker 对象上的 worker.on('message') 事件为父线程提供访问。
【Like Web Workers and the node:cluster module, two-way communication
can be achieved through inter-thread message passing. Internally, a Worker has
a built-in pair of MessagePorts that are already associated with each
other when the Worker is created. While the MessagePort object on the parent
side is not directly exposed, its functionalities are exposed through
worker.postMessage() and the worker.on('message') event
on the Worker object for the parent thread.】
要创建自定义消息通道(相比使用默认的全局通道更推荐,因为它有助于关注点分离),用户可以在任意线程上创建一个 MessageChannel 对象,并通过已有的通道(例如全局通道)将该 MessageChannel 上的一个 MessagePort 传递给另一个线程。
【To create custom messaging channels (which is encouraged over using the default
global channel because it facilitates separation of concerns), users can create
a MessageChannel object on either thread and pass one of the
MessagePorts on that MessageChannel to the other thread through a
pre-existing channel, such as the global one.】
有关消息传递的更多信息,以及可以成功通过线程屏障传输的 JavaScript 值类型,请参见 port.postMessage()。
【See port.postMessage() for more information on how messages are passed,
and what kind of JavaScript values can be successfully transported through
the thread barrier.】
import assert from 'node:assert';
import {
Worker, MessageChannel, MessagePort, isMainThread, parentPort,
} from 'node:worker_threads';
if (isMainThread) {
const worker = new Worker(new URL(import.meta.url));
const subChannel = new MessageChannel();
worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
subChannel.port2.on('message', (value) => {
console.log('received:', value);
});
} else {
parentPort.once('message', (value) => {
assert(value.hereIsYourPort instanceof MessagePort);
value.hereIsYourPort.postMessage('the worker is sending this');
value.hereIsYourPort.close();
});
}'use strict';
const assert = require('node:assert');
const {
Worker, MessageChannel, MessagePort, isMainThread, parentPort,
} = require('node:worker_threads');
if (isMainThread) {
const worker = new Worker(__filename);
const subChannel = new MessageChannel();
worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
subChannel.port2.on('message', (value) => {
console.log('received:', value);
});
} else {
parentPort.once('message', (value) => {
assert(value.hereIsYourPort instanceof MessagePort);
value.hereIsYourPort.postMessage('the worker is sending this');
value.hereIsYourPort.close();
});
}