JavaScript - Worker API



Web Worker API

worker API 是一个 Web API,它允许我们在后台线程中运行 JavaScript 代码。每当网页在浏览器中加载时,它都会在浏览器中加载每个 <script> 标记后变为交互式。Web Worker 允许用户与网页交互,而无需在浏览器中加载整个 JavaScript 代码。它增加了网页的响应时间。

创建 Web Worker 文件

要创建 Web Worker,您需要在外部文件中编写脚本,您需要在不同的文件中执行该脚本。

文件名应具有“.js”扩展名。

在下面的 JavaScript 代码中,我们定义了 counter() 函数。我们在函数中使用了 setTimeout() 方法,每 1000 毫秒后调用 counter() 函数。

代码的重要部分是 postMessage() 方法。它用于在主线程中发送数据。


function counter() {
	 	 postMessage(data); // 将数据发送到主线程
	 	 setTimeout("counter()", 1000);
}
counter();

检查 Web Worker 支持

在创建 Web Worker 之前,您应该检查您的浏览器是否支持 Web Worker。您可以使用 typeof 运算符来检查这一点。


if (typeof(Worker) !== "undefined") {
	 	 //"您的浏览器支持Web worker!";
} else {
	 	 //"您的浏览器不支持Web worker!";
}

创建 Web Worker 对象

创建外部 JavaScript 文件后,您需要通过将外部 JavaScript 文件的路径作为参数传递来创建新的 Worker 对象,如下所示。


 const workerObj = new Worker("testWorker.js");

要从我们使用 postMessage() 方法发送的 worker 文件中获取消息主线程,您可以在 worker 对象上使用 'onmessage' 事件,如下所示。


workerObj.onmessage = function(e) {
	 // 使用 event.data
};

终止 Web Worker 的执行

当您开始执行 Web Worker 脚本时,它会继续执行,直到您终止执行。

您可以使用 terminate() 方法终止 Web Worker 的执行,如下所示。


 workerObj.terminate();

示例:Web Worker 的完整程序

文件名: - index.html

在下面的代码中,我们定义了 startWorker() 和 stopWorker() 函数来启动和停止 worker 的执行。

在 startWorker() 函数中,首先检查浏览器是否支持 worker。之后,我们检查 worker 的任何实例是否正在运行。如果没有,我们使用外部文件中定义的脚本创建 Worker 对象的新实例。

之后,我们在 worker 对象上添加了 'onmessage' 事件。因此,每当它从外部脚本文件获取数据时,它都会打印数据并执行其他操作。

在 stopWorker() 函数中,我们将 terminate() 方法与 workerObj 对象一起使用,以终止 worker 的执行。


<html>
<body>
<button onclick = "startWorker()"> Start Counter </button>
<button onclick = "stopWorker()"> Stop Counter </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) {   // 从web worker获取消息
	 	 	 	 	 	 	 	output.innerHTML += "Event data is: " + event.data + "<br>";
	 	 	 	 	 	 };
	 	 	 	 	}
	 	 	 } else {
	 	 	 	 	output.innerHTML += "您的浏览器不支持Web worker。";
	 	 	 }
	 	}
	 	function stopWorker() { // 停止web worker。
	 	 	 if (typeof workerObj !== "undefined") {
	 	 	 	 	workerObj.terminate();
	 	 	 	 	workerObj = undefined;
	 	 	 }
	 	}
</script>
</body>
</html>

文件名: - app.js

在下面的代码中,我们定义了 counter() 函数。在 counter() 函数中,我们使用 setTimeOut() 方法在每秒后调用 counter() 函数。它还使用 postMessage() 方法将数据发布到主线程中。


var i = 0;
function timedCount() {
	 	i = i + 1;
	 	postMessage(i);
	 	setTimeout("timedCount()",500);
}
timedCount();

输出

要运行上述代码,您需要确保 index.html 和 app.js 文件位于实时 Web 服务器上。您也可以使用 localhost.此外,请确保在 index.html 文件内的 Worker 对象中为 app.js 文件添加正确的路径。

Web Worker API

您还可以在同一文件中使用多个工作程序在后台运行多个脚本。

Web Worker 使用案例

上面的例子很简单,在这种情况下,你不需要使用 Web Worker,但它仅用于演示。

以下是 Web Worker 的实时用例。

  • 当您需要执行大型或复杂的数学脚本时
  • 在 HTML 游戏中,您可以使用 Web Worker
  • 如果您想提高网站性能
  • 在并行下载中,当您需要执行多个线程时
  • 对于后台数据同步
  • 在机器学习中
  • 用于生成报告
  • 处理音频和视频

Web Worker 和 DOM

由于您需要在外部文件中为 Web Worker 定义脚本,因此不能在外部文件中使用以下对象。

  • window 对象
  • document 对象
  • parent 对象

但是,您可以在 Web Worker 中使用以下对象。

  • location 对象
  • navigator 对象
  • Application 缓存 (应用程序缓存)
  • 使用 importScripts() 导入外部脚本
  • XMLHttpRequest (XMLHttp请求)