首页 / HTML5 入门教程 / Web Workers 多线程

HTML5 入门教程

Web Workers 多线程

本教程共 110 篇 · 第 94 篇 · 更新于 2026-07-28 · 约 4 分钟阅读

HTML5HTML5 入门教程Web Workers多线程Worker后台计算

94. Web Workers 多线程

本节目标:理解为什么需要 Web Worker,学会创建 Worker、主线程和 Worker 之间通信的基本模式。

为什么需要 Web Worker

JavaScript 是单线程的。所有代码都在一个主线程上跑。如果有个耗时任务(大数组排序、复杂计算),页面就会卡住不动。

Web Worker 就是来解决这个问题的。它创建一个独立的后台线程,在里面执行耗时任务,主线程继续响应用户操作。

关键限制

Worker 有它的规矩:

  • 不能操作 DOM:Worker 里没有 documentwindow 对象
  • 不能访问页面变量:Worker 运行在独立的全局上下文
  • 通过消息通信:主线程和 Worker 用 postMessage 发消息

创建和使用

第一步:创建 Worker

const worker = new Worker("worker.js");

第二步:主线程向 Worker 发消息

worker.postMessage({ cmd: "calc", num: 1000000 });

第三步:主线程接收 Worker 回复

worker.onmessage = function (e) {
  console.log("Worker 算完了:", e.data);
};

Worker 文件(worker.js)

// Worker 内部监听消息
onmessage = function (e) {
  const num = e.data.num;

  // 模拟耗时计算
  let result = 0;
  for (let i = 0; i < num; i++) {
    result += i;
  }

  // 把结果发回主线程
  postMessage(result);
};

完整示例(主页面)

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>
<body>
  <button onclick="startCalc()">开始计算</button>
  <button onclick="sayHi()">打个招呼</button>
  <p id="result"></p>

  <script>
    const worker = new Worker("worker.js");

    function startCalc() {
      const start = Date.now();
      worker.postMessage({ num: 500000000 });
    }

    worker.onmessage = function (e) {
      document.getElementById("result").textContent =
        "计算结果:" + e.data;
    };

    // 这个按钮在 Worker 计算时不卡
    function sayHi() {
      alert("计算的同时我还能点!");
    }
  </script>
</body>
</html>

内联 Worker(不需要外部文件)

如果 Worker 代码不想单独写文件,可以用 Blob URL 内联:

const workerCode = `
  onmessage = function(e) {
    postMessage("收到了:" + e.data);
  };
`;

const blob = new Blob([workerCode], { type: "application/javascript" });
const url = URL.createObjectURL(blob);
const worker = new Worker(url);

worker.onmessage = function (e) {
  console.log(e.data);
};

worker.postMessage("你好 Worker");
Note

内联 Worker 在小项目或演示时很方便,但实际开发中建议把 Worker 代码拆成独立文件,好维护。

Worker 生命周期

// 创建后自动启动
const worker = new Worker("worker.js");

// 用完可以手动终止
worker.terminate();

// Worker 内部也可以自己关闭
// self.close();

实际用途

场景说明
大数组排序/过滤几万条数据的排序不卡页面
图像/视频处理像素级运算、滤镜
加密解密哈希计算、加解密运算
数据解析解析大文件(CSV、JSON)
物理模拟游戏中的碰撞检测、路径规划

共享内存:SharedArrayBuffer

如果需要主线程和 Worker 共享数据,可以用 SharedArrayBuffer。但它涉及原子操作,比较复杂,这里只作了解。

普通场景用 postMessage 发数据就行,虽然会复制一份,但大多数情况够用。

Warning

Web Worker 不能访问 DOM。如果你想在 Worker 里操作页面,做不到。Worker 的职责就是计算,算完把结果告诉主线程,让主线程去更新页面。