JavaScript 如何使用Web Worker在单独的线程中运行函数
JavaScript是一种流行的轻量级、解释编译的客户端脚本语言。大多数Web应用程序在客户端使用JavaScript。通过为JavaScript提供运行时环境,它也可以在服务器端(Node.js)使用。在本文中,我们将介绍如何使用JavaScript的Web Worker在单独的线程中运行函数。
先决条件:
- Web Workers
- JavaScript函数
什么是Web Worker?
许多编程语言如Java、C++等都具有多线程的功能。Web Worker简单地允许我们在JavaScript中使用多线程功能。如果任何耗时的函数阻塞了DOM,我们可以使用Web Worker在后台运行它,从而保持DOM的整洁。
Web Worker面临的障碍:
- Web Worker无法访问DOM。
- 无法复制的数据无法传递给Web Worker。更准确地说,无法使用结构化克隆算法克隆的数据无法传递给Web Worker。
将函数传递给Web Worker是一项具有挑战性的任务,因为函数无法通过结构化克隆算法进行克隆。当将函数传递给Web Worker时,会抛出DataCloneError。
将函数传递给Web Worker的技巧:
步骤1: 将要传递的函数转换为字符串,使用 toString()方法 。字符串可以通过结构化克隆算法复制并传递给Web Worker。下面的代码将函数转换为字符串。
myString = myFunction.toString()
步骤2: 将字符串传递给Web Worker。
步骤3: 使用Function()构造函数将字符串转换回Web Worker内部的函数。下面的代码将字符串转换回函数。
convertedFunction = new Function("return" + myString)();
步骤4: 评估函数。
例子: 我们将随机移动文本GeeksForGeeks。随机位置由Web Worker计算得出。我们将创建两个文件,一个用于DOM,一个用于Web Worker。
index.html: 按照以下方式编辑index.html:
HTML
<!DOCTYPE html>
<html lang="en">
<body style="height: 90vh; width: 93vw;">
<h1 style="color: #2f8d46; position: absolute;">
GeeksForGeeks
</h1>
<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>
</body>
</html>
worker.js: 以以下方式编辑worker.js:
Javascript
self.onmessage = ({data}) => {
// Converting the string back to a string
const func = new Function(
"return" + data.function
)();
// Evaluates the function and sends
// the data back to the main file
const timerFunction = () => {
randomPositions = func(
data.arguments[0], data.arguments[1]
);
self.postMessage(randomPositions);
}
// Runs the timerFunction at every
// interval specified in the arguments.
setInterval(() => {
timerFunction();
}, data.arguments[2])
}
输出: