> 文章列表 > 初识 web workers

初识 web workers

初识 web workers

web workers 简介

Web Workers 是 HTML5 新增的一项 API,它允许在后台线程中运行 JavaScript 代码,从而避免阻塞主线程并提高 Web 应用程序的响应性能。通过将计算密集型任务(如大量数据的处理)放在 Worker 线程中,可以使 Web 应用程序更加流畅和快速响应用户操作。

  • Web Workers 是运行在主线程之外的 JavaScript 线程,可以执行计算密集型操作、长时间运行的代码或其他繁重的任务。

  • Web Workers 使用 postMessage() 方法与主线程通信,并使用 onmessage 事件侦听器接收来自主线程的消息。

  • 通过调用 Worker() 构造函数可以创建一个新的 Web Worker,该构造函数需要传递一个 JavaScript 文件路径或者直接传递一个字符串形式的 JavaScript 代码。

  • 在 Web Worker 中无法访问 DOM,因为它们运行在不同的上下文环境中。但是,Web Workers 可以通过 XMLHttpRequest 和 fetch 与服务器进行通信。

  • 多个 Web Workers 可以同时运行,它们互相独立且不能共享内存。如果多个 Web Workers 需要共享数据,则必须使用 postMessage() 方法将数据从一个 Web Worker 发送到另一个 Web Worker。

  • Web Workers 可以通过 terminate() 方法终止运行,也可以通过 close() 方法关闭与它们的通信通道。

  • 如果需要使用 Web Workers 来处理较大的数据集合,那么可以考虑使用 SharedArrayBuffer 和 Atomics API 来实现更高效的数据共享和同步。

创建一个 web Workers

1、在 HTML 文件中引入一个 JavaScript 文件,该文件将会创建 Web Worker:

<!DOCTYPE html>
<html><head><title>Web Workers Demo</title></head><body><script src="worker.js"></script><script>// 创建一个新的 Web Workerconst worker = new Worker('worker.js');// 向 Web Worker 发送消息worker.postMessage('Hello, worker!');// 监听 Web Worker 返回的消息worker.onmessage = function (event) {console.log('Received message from worker:', event.data);};</script></body>
</html>

2、在 worker.js 文件中编写 Web Worker 的代码

// 接收来自主线程的消息
self.onmessage = function (event) {console.log('Received message in worker:', event.data);// 执行一些计算密集型操作const result = doSomeWork();// 将结果发送回主线程self.postMessage(result);
};// 模拟一个计算密集型操作
function doSomeWork() {let sum = 0;for (let i = 0; i < 1000000000; i++) {sum += i;}return sum;
}

使用示例

以下是一个使用 Web Workers 的简单 demo,它计算从 1 到给定数字之间所有整数的和,同时不会阻塞主线程:
在 HTML 文件中插入以下代码:

<!DOCTYPE html>
<html><head><title>Web Worker Demo</title><script>function calculateSum() {// 获取用户输入的数字const number = parseInt(document.getElementById('number').value);// 创建一个新的Web Worker对象const worker = new Worker('sum_worker.js');// 设置消息监听器,以便在计算完成时接收结果worker.addEventListener('message', (event) => {document.getElementById('result').textContent = event.data;});// 向Web Worker发送消息,启动计算worker.postMessage(number);}</script></head><body><label for="number">请输入一个数字:</label><input type="number" id="number" /><button onclick="calculateSum()">计算总和</button><p id="result"></p></body>
</html>

在同一目录下创建一个名为 sum_worker.js 的 JavaScript 文件,包含以下代码:

// 监听消息事件
self.addEventListener('message', (event) => {// 获取传递过来的数字const number = event.data;// 计算总和let sum = 0;for (let i = 1; i <= number; i++) {sum += i;}// 发送计算结果回主线程self.postMessage(sum);
});

现在你可以在浏览器中打开这个 HTML 文件,输入一个数字,并点击“计算总和”按钮。Web Worker 将开始计算总和,而主线程不会被阻塞,你可以在页面上做其他的事情。一旦计算完成,Web Worker 将发送消息回主线程,显示计算结果。

关闭 worker

Worker 在不断创建,旧的 Worker 也不会自动关闭。这样会造成资源的浪费。那么,就需要我们手动关闭 Worker。
我们先给 Worker 增加一个 close()。在 worker 里的任务执行成功后主动关闭 worker

self.close();