Web Worker API 是一个允许我们在后台线程中运行 JavaScript 代码的 Web API。每当网页在浏览器中加载时,它会在每个 <script>
标签加载后变得可交互。Web 工人允许用户在不加载整个 JavaScript 代码的情况下与网页进行交互,从而提高了网页的响应速度。
创建一个 Web Worker 文件
为了创建一个 Web 工人,你需要在一个外部文件中编写脚本,然后在另一个文件中执行这个外部文件。
文件名应该有一个 .js
扩展名。
在下面的 JavaScript 代码中,我们定义了一个 counter()
函数。我们在函数内部使用了 setTimeout()
方法来每隔 1000 毫秒调用一次 counter()
函数。
代码的重要部分是 postMessage()
方法。它用来向主线程发送数据。
function counter() {
postMessage(data);
setTimeout("counter()", 1000);
}
counter();
检查 Web Worker 支持
在创建 Web 工人之前,你应该检查你的浏览器是否支持 Web 工人。你可以使用 typeof
操作符来检查这一点。
if (typeof(Worker) !== "undefined") {
} else {
}
创建一个 Web Worker 对象
创建了外部 JavaScript 文件之后,你需要通过传递外部 JavaScript 文件的路径作为参数来创建一个新的 Worker 对象,如下所示。
const workerObj = new Worker("testWorker.js");
为了从 worker 文件接收消息(我们使用 postMessage()
方法发送),你可以像下面这样在 Worker 对象上使用 onmessage
事件。
workerObj.onmessage = function(e) {
};
终止 Web Worker 的执行
当你开始执行 Web 工人脚本时,它会一直执行直到你终止它。
你可以使用 terminate()
方法来终止 Web 工人的执行,如下所示。
workerObj.terminate();
示例:完整的 Web Worker 程序
文件名: index.html
在下面的代码中,我们定义了 startWorker()
和 stopWorker()
函数来启动和停止 worker 的执行。
在 startWorker()
函数中,首先我们检查浏览器是否支持 workers。之后,我们检查是否有 worker 实例正在运行。如果没有,我们就使用外部文件中定义的脚本创建一个新的 Worker 对象实例。
之后,我们在 worker 对象上添加了 onmessage
事件。所以每当它从外部脚本文件接收到数据时,就会打印出来并执行其他操作。
在 stopWorker()
函数中,我们使用 terminate()
方法与 workerObj
对象一起终止 worker 的执行。
<html>
<body>
<button onclick = "startWorker()"> 开始计数 </button>
<button onclick = "stopWorker()"> 停止计数 </button>
<div id = "output"></div>
<script>
let output = document.getElementById('output');
let workerObj;
function startWorker() {
if (typeof (Worker) !== "undefined") {
if (typeof workerObj === "undefined") {
workerObj = new Worker("app.js");
workerObj.onmessage = function (event) {
output.innerHTML += "事件数据是: " + event.data + "<br>";
};
}
} else {
output.innerHTML += "Web 工人不被你的浏览器支持。";
}
}
function stopWorker() {
if (typeof workerObj !== "undefined") {
workerObj.terminate();
workerObj = undefined;
}
}
</script>
</body>
</html>
文件名: app.js
在下面的代码中,我们定义了一个 timedCount()
函数。在 timedCount()
函数中,我们使用了 setTimeOut()
方法每隔一秒调用一次 timedCount()
函数。它还使用 postMessage()
方法将数据发布到主线程。
var i = 0;
function timedCount() {
i = i + 1;
postMessage(i);
setTimeout("timedCount()",500);
}
timedCount();
输出
为了运行上述代码,你需要确保 index.html
和 app.js
文件位于活动的 Web 服务器上。你也可以使用本地主机。同时,确保在 index.html
文件内的 Worker 对象中添加了正确的 app.js
文件路径。
Web Worker API
你还可以在同一文件中使用多个工人来在后台运行多个脚本。
Web Worker 应用场景
上面的例子很简单,在这种情况下,你不需要使用 Web 工人,但只是为了演示。
以下是 Web 工人的实际应用场景:
Web Workers 与 DOM
由于需要在外部文件中定义 Web 工人的脚本,所以在外部文件中不能使用以下对象:
-
-
The document object (文档对象)
-
然而,你可以在 Web 工人中使用以下对象:
-
The location object (位置对象)
-
The navigator object (导航器对象)
-
The Application Cache (应用缓存)
-
使用
importScripts()
导入外部脚本
-