Skip to content

Worker threads

node:worker_threads 模块允许使用并行执行 JavaScript 的线程。要访问它,请执行以下操作:

js
const worker = require('node:worker_threads');

工作线程(线程)对于执行 CPU 密集型 JavaScript 操作非常有用。它们对 I/O 密集型工作没有多大帮助。Node.js内置异步 I/O 操作比 Workers 更高效。

与 或 cluster 不同 child_processworker_threads 可以共享内存。他们通过传输 ArrayBuffer 实例或共享 SharedArrayBuffer 实例来实现。

js
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 都会自动接收自己的环境数据副本。

js
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 线程内运行。

js
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')

js
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 队列中最早的消息。

js
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 线程应共享对同一组环境变量的读取和写入访问权限。

js
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 实例都是唯一的。

js
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() 一样克隆数据。

js
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!'.
}

Released under the MIT License.