类:Worker
¥Class: Worker
-
¥Extends: <EventEmitter>
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流可能被父线程重定向。¥The
process.stdin,process.stdout, andprocess.stderrstreams may be redirected by the parent thread. -
require('node:worker_threads').isMainThread属性被设置为false。¥The
require('node:worker_threads').isMainThreadproperty is set tofalse. -
require('node:worker_threads').parentPort消息端口可用。¥The
require('node:worker_threads').parentPortmessage port is available. -
process.exit()不会停止整个程序,只是单个线程,且process.abort()不可用。¥
process.exit()does not stop the whole program, just the single thread, andprocess.abort()is not available. -
设置群组或用户标识的
process.chdir()和process方法不可用。¥
process.chdir()andprocessmethods that set group or user ids are not available. -
process.env是父线程的环境变量的副本,除非另有说明。对副本的更改在其他线程中不可见,且对原生插件不可见(除非将worker.SHARE_ENV作为env选项传给Worker构造函数)。在 Windows 上,与主线程不同,环境变量的副本以区分大小写的方式运行。¥
process.envis a copy of the parent thread's environment variables, unless otherwise specified. Changes to one copy are not visible in other threads, and are not visible to native add-ons (unlessworker.SHARE_ENVis passed as theenvoption to theWorkerconstructor). On Windows, unlike the main thread, a copy of the environment variables operates in a case-sensitive manner. -
process.title不能修改。¥
process.titlecannot be modified. -
信号不通过
process.on('...')传送。¥Signals are not delivered through
process.on('...'). -
worker.terminate()被调用时,执行可能在任何时候停止。¥Execution may stop at any point as a result of
worker.terminate()being invoked. -
来自父进程的进程间通信通道不可访问。
¥IPC channels from parent processes are not accessible.
-
不支持
trace_events模块。¥The
trace_eventsmodule is not supported. -
如果原生附加组件满足 特定条件,则只能从多个线程加载。
¥Native add-ons can only be loaded from multiple threads if they fulfill certain conditions.
在其他 Worker 中创建 Worker 实例是可能的。
¥Creating Worker instances inside of other Workers is possible.
与 网络工作线程 和 node:cluster 模块 一样,可以通过线程间消息传递实现双向通信。在内部,Worker 有一对内置的 MessagePort,它们在创建 Worker 时已经相互关联。虽然父端的 MessagePort 对象没有直接暴露,但其功能通过父线程 Worker 对象上的 worker.postMessage() 和 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();
});
}