Workers

Workers are useful when you application needs to perform computationally intensive tasks, such as image processing.

To create a worker, call the Worker() constructor, passing a URL with worker script which must have the same origin as the containing document.

const worker = new Worker("worker.js");

You can send data to the worker with postMessage() method. The value you pass to postMessage() will be copied using the structured clone algorithm, meaning you can pass any primitive values as well as objects, arrays, typed arrays, Maps, Sets, etc.

worker.postMessage("hello worker");

You can receive messages from a worker by listening to the "message" events on the Worker object. You terminate the worker by calling the terminate() method on the Worker object.

worker.onmessage = (event) => {
  const data = event.data;
  console.log("Main script received:", data);
  worker.terminate();
};

The worker script is executed in a new execution environment with WorkerGlobalScope object as the global object as soon as it is created. The worker utilizes onmessage() event handler to listen to incoming messages and postMessage() method to send messages out. You terminate the worker by invoking the close() method inside worker script. The global self property refers to the global WorkerGlobalScope object.

onmessage = (event) => {
  let data = event.data;
  console.log("Worker recieved:", data);
  postMessage("Worker recieved: " + data);
  close();
};

If you pass a second argument to the Worker() constructor, and if that object has a name property, then the value of that property becomes the value of the name property in the workers' global object.

const myWorker = new Worker("my-worker.js", { name: "myWorker" });

To import other scripts into the worker code, you can use importScripts() function that takes a URL with a JavaScript file.

importScripts("script1.js", "script2.js");

In order to use modules in workers, you must pass a second argument to the Worker() constructor which has a type property with the value "module".

const moduleWorker = new Worker("module.js", { type: "module" });

You can handle any errors by listening to the "error" events inside worker.

self.onerror = (error) => {
  console.log(
    `Error in worker at ${error.filename}:${error.lineno}: ${error.message}`
  );
  error.stopPropagation();
};

Alternatively, you can handle error events on the Worker object outside the worker.

worker.onerror = (error) => {
  console.log(
    `Error in worker at ${error.filename}:${error.lineno}: ${error.message}`
  );
  error.stopPropagation();
};

You can handle unhandled promise rejections by adding an event listener for "unhandledrejection" event within the worker script. This can help you catch and handle errors that occur in asynchronous code within the worker.