How to run a function in a separate thread by using a Web Worker in JavaScript ?
JavaScript is a popular lightweight, interpreted compiled client-side scripting language. Most Web Applications use JavaScript on the client side. By providing JavaScript with a runtime environment, it can also be used on the server-side (Node.js). In this article, we will cover how to run a function on a separate thread by using a JavaScript Web Worker.
Pre Requisites:
What is a Web Worker?
Many languages such as Java, C++ etc have the functionality of multi-threading. A web worker simply allows us to use the functionality of multi-threading in JavaScript. If any time-consuming function is blocking the DOM, we can use web workers to run it in the background keeping the DOM clutter-free.
Obstacles Faced by Web Workers:
- A Web Worker does not have access to the DOM.
- Data that cannot be reproduced can’t be passed to the web worker. More precisely data that cannot be cloned with the structured clone algorithm, can’t be passed to the web worker.
Passing a function to a web worker is a challenging task, as a function cannot be cloned by the structured clone algorithm. A DataCloneError is thrown when a function is passed to a web worker.
The trick to passing functions to a web worker:
Step 1: Convert the function to be passed into a string by using the toString() method. Strings can be passed to a web worker as they can be duplicated by the structured clone algorithm. The below code converts the function to a string.
myString = myFunction.toString()
Step 2: Pass the string to the web worker.
Step 3: Convert the string back to a function inside the web worker by using the Function() constructor. The below code converts the string back to a function.
convertedFunction = new Function("return" + myString)();
Step 4: Evaluate the function.
Example: We are going to move the text GeeksForGeeks randomly. The random position is calculated by the web worker. We are going to create two files, one for the DOM and one for the web worker.
index.js: Edit index.js in the following manner:
<!DOCTYPE html>
<html lang="en">
<body style="height: 90vh; width: 93vw;">
<h1 style="color: #2f8d46; position: absolute;">
GeeksForGeeks
</h1>
</body>
<script>
// Updated the position on the DOM
const updatePosition = (element, randomPosition) => {
element.style.top = randomPosition[0] + "px";
element.style.left = randomPosition[1] + "px";
}
// Calculates the random position
const getRandomPosition =
(height, width) =>
[Math.floor(Math.random() * height),
Math.floor(Math.random() * width)];
// Creating a Web Worker
const worker = new Worker('worker.js');
// Getting the GeeksForGeeks text
const title = document.querySelector('h1');
// Updated the position on receiving the random position
worker.onmessage = (event) =>
updatePosition(title, event.data);
// Passing the function to the Web Worker
worker.postMessage({
// Converting the function to a string
function: getRandomPosition.toString(),
// Arguments passed to the function
arguments: [document.body.offsetHeight,
document.body.offsetWidth, 1000]
})
</script>
</html>
Please Login to comment...