Skip to content

HTML5 Web Workers

JavaScript 是单线程的,这意味着它在同一时间只能做一件事。如果一个脚本需要执行一个非常耗时、计算密集的任务(例如,处理大量数据、复杂的数学计算),它会阻塞主线程,导致整个用户界面 (UI) 被冻结,页面无法响应用户的任何操作(如点击、滚动),从而带来极差的用户体验。

Web Workers 就是 HTML5 为解决这个问题而引入的。Web Worker 是一个在后台运行的 JavaScript 脚本,它独立于主线程,不会影响页面的性能和响应。

Web Worker 的特点

  • 后台线程: Worker 在一个与主线程分离的后台线程中运行。
  • 无 UI 阻塞: 你可以将耗时的计算任务交给 Worker,而主线程可以继续自由地处理用户交互和 DOM 更新。
  • 受限的访问: 出于线程安全的考虑,Worker 无法直接访问主线程的 window 对象、document 对象和父页面的 DOM 节点。
  • 通信机制: Worker 通过消息传递机制与主线程进行通信。

如何使用 Web Worker

使用 Web Worker 分为三个主要步骤:创建 Worker、在主线程和 Worker 之间收发消息、终止 Worker。

1. 创建 Worker 文件

首先,你需要创建一个独立的 .js 文件,这里我们称之为 demo_worker.js。这个文件将包含你希望在后台执行的代码。

demo_worker.js:

javascript
// 一个简单的计数任务
let i = 0;

function timedCount() {
  i = i + 1;
  // 将当前计数值发送回主线程
  postMessage(i);
  setTimeout(timedCount, 500);
}

timedCount();

postMessage() 是 Worker 向主线程发送消息的方法。

2. 在主页面中创建和控制 Worker

在你的主 HTML 页面中,你可以创建并与 Worker 进行交互。

html
<p>计数: <output id="result"></output></p>
<button onclick="startWorker()">开始 Worker</button> 
<button onclick="stopWorker()">停止 Worker</button>

<script>
let w;

function startWorker() {
  // 检查浏览器是否支持 Web Worker
  if (typeof(Worker) !== "undefined") {
    // 如果 w 还未创建,则创建一个新的 Worker
    if (typeof(w) == "undefined") {
      w = new Worker("demo_worker.js");
    }
    // 监听来自 Worker 的消息
    w.onmessage = function(event) {
      document.getElementById("result").innerHTML = event.data;
    };
  } else {
    document.getElementById("result").innerHTML = "抱歉,您的浏览器不支持 Web Workers...";
  }
}

function stopWorker() { 
  // 终止 Worker
  if (typeof(w) !== "undefined") {
    w.terminate();
    w = undefined; // 重置 Worker 变量
  }
}
</script>
  • new Worker("demo_worker.js"): 创建一个新的 Web Worker 对象。
  • w.onmessage: 设置一个事件监听器,用于接收 Worker 通过 postMessage() 发送回来的数据。数据包含在 event.data 属性中。
  • w.terminate(): 立即终止 Worker 的运行。这是一个从主线程侧停止 Worker 的方法。

这个例子清晰地展示了如何将一个持续运行的计数任务放到后台,而主页面可以自由地响应用户的“开始”和“停止”操作,UI 不会卡顿。

本站内容仅供学习和研究使用。