Node.js v12.1.0 Documentation


Worker Threads#

Stability: 1 - Experimental

The worker_threads module enables the use of threads that execute JavaScript in parallel. To access it:

const worker = require('worker_threads');

Workers (threads) are useful for performing CPU-intensive JavaScript operations. They will not help much with I/O-intensive work. Node.js’s built-in asynchronous I/O operations are more efficient than Workers can be.

Unlike child_process or cluster, worker_threads can share memory. They do so by transferring ArrayBuffer instances or sharing SharedArrayBuffer instances.

const {
  Worker, isMainThread, parentPort, workerData
} = require('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(`Worker stopped with exit code ${code}`));
      });
    });
  };
} else {
  const { parse } = require('some-js-parsing-library');
  const script = workerData;
  parentPort.postMessage(parse(script));
}

The above example spawns a Worker thread for each parse() call. In actual practice, use a pool of Workers instead for these kinds of tasks. Otherwise, the overhead of creating Workers would likely exceed their benefit.

worker.isMainThread#

Is true if this code is not running inside of a Worker thread.

const { Worker, isMainThread } = require('worker_threads');

if (isMainThread) {
  // This re-loads the current file inside a Worker instance.
  new Worker(__filename);
} else {
  console.log('Inside Worker!');
  console.log(isMainThread);  // Prints 'false'.
}

worker.moveMessagePortToContext(port, contextifiedSandbox)#

Transfer a MessagePort to a different vm Context. The original port object will be rendered unusable, and the returned MessagePort instance will take its place.

The returned MessagePort will be an object in the target context, and will inherit from its global Object class. Objects passed to the port.onmessage() listener will also be created in the target context and inherit from its global Object class.

However, the created MessagePort will no longer inherit from EventEmitter, and only port.onmessage() can be used to receive events using it.

worker.parentPort#

If this thread was spawned as a Worker, this will be a MessagePort allowing communication with the parent thread. Messages sent using parentPort.postMessage() will be available in the parent thread using worker.on('message'), and messages sent from the parent thread using worker.postMessage() will be available in this thread using parentPort.on('message').

const { Worker, isMainThread, parentPort } = require('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.SHARE_ENV#

A special value that can be passed as the env option of the Worker constructor, to indicate that the current thread and the Worker thread should share read and write access to the same set of environment variables.

const { Worker, SHARE_ENV } = require('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#

An integer identifier for the current thread. On the corresponding worker object (if there is any), it is available as worker.threadId. This value is unique for each Worker instance inside a single process.

worker.workerData#

An arbitrary JavaScript value that contains a clone of the data passed to this thread’s Worker constructor.

The data is cloned as if using postMessage(), according to the HTML structured clone algorithm.

const { Worker, isMainThread, workerData } = require('worker_threads');

if (isMainThread) {
  const worker = new Worker(__filename, { workerData: 'Hello, world!' });
} else {
  console.log(workerData);  // Prints 'Hello, world!'.
}

Class: MessageChannel#

Instances of the worker.MessageChannel class represent an asynchronous, two-way communications channel. The MessageChannel has no methods of its own. new MessageChannel() yields an object with port1 and port2 properties, which refer to linked MessagePort instances.

const { MessageChannel } = require('worker_threads');

const { port1, port2 } = new MessageChannel();
port1.on('message', (message) => console.log('received', message));
port2.postMessage({ foo: 'bar' });
// Prints: received { foo: 'bar' } from the `port1.on('message')` listener

Class: MessagePort#

Instances of the worker.MessagePort class represent one end of an asynchronous, two-way communications channel. It can be used to transfer structured data, memory regions and other MessagePorts between different Workers.

With the exception of MessagePorts being EventEmitters rather than EventTargets, this implementation matches