Skip to content

Web Worker

使用Demo

一个最常见的使用 Web Workers 的例子就是计算斐波那契数列。斐波那契数列是一个递归定义的数列,其特点是每个数都是前两个数之和,即:0、1、1、2、3、5、8、13、21、34……。由于这个数列的计算需要进行大量的递归运算,因此可以使用 Web Workers 将计算任务分发到多个线程中并行处理,提高计算效率。

以下是一个简单的示例代码,演示了如何使用 Web Workers 计算斐波那契数列:

在 HTML 文件中,我们需要创建一个 Web Worker 脚本,并将其指定为外部脚本,如下所示:

html
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
  <title>Web Worker Demo</title>
</head>
<body>
  <h1>斐波那契数列计算器</h1>
  <p>请输入要计算的数列长度:</p>
  <input type="text" id="num" value="10">
  <button onclick="startWorker()">开始计算</button>
  <div id="result"></div>

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

    function startWorker() {
      var num = document.getElementById("num").value;
      worker.postMessage(num);
    }

    worker.onmessage = function(event) {
      document.getElementById("result").innerHTML = event.data;
    };
  </script>
</body>
</html>

在 JavaScript 文件中,我们需要编写 Web Worker 的逻辑,实现斐波那契数列的计算并将结果传递回主线程:

js
// work.js
function fib(num) {
  if (num <= 1) {
    return num;
  } else {
    return fib(num - 1) + fib(num - 2);
  }
}

onmessage = function(event) {
  var result = [];
  var num = parseInt(event.data, 10);
  for (var i = 0; i < num; i++) {
    result.push(fib(i));
  }
  postMessage(result);
};

注意,在 Web Worker 中无法直接访问 DOM,因此不能直接操作 HTML 页面。在本例中,我们通过 postMessage 和 onmessage 方法实现了主线程和 Worker 线程之间的通信,从而将计算结果返回到 HTML 页面上。

在运行这个示例代码时,用户可以在页面上输入要计算的斐波那契数列长度,然后点击“开始计算”按钮,程序就会启动 Web Worker 进行计算,并将结果显示在页面上。

动态生成

worker.js 文件可以动态生成。

在实际应用中,有时我们需要根据不同的需求和场景动态生成 Web Worker 脚本,而不是将其作为一个外部脚本文件引入。这种情况下,我们可以使用 Blob 对象来创建动态的 Web Worker 脚本。

以下是一个示例代码,演示了如何动态生成 Web Worker 脚本:

js
function startWorker() {
  var num = document.getElementById("num").value;

  // 创建并编译 worker 脚本
  var workerSrc = "self.onmessage = function(event) { " +
                  "var num = parseInt(event.data, 10); " +
                  "var result = fib(num); " +
                  "self.postMessage(result); " +
                  "}; " +
                  "function fib(num) { " +
                  "if (num <= 1) { " +
                  "return num; " +
                  "} else { " +
                  "return fib(num - 1) + fib(num - 2); " +
                  "} " +
                  "}";
  var blob = new Blob([workerSrc], { type: "text/javascript" });
  var worker = new Worker(URL.createObjectURL(blob));

  // 发送消息给 worker 并接收结果
  worker.postMessage(num);
  worker.onmessage = function(event) {
    document.getElementById("result").innerHTML = event.data;
  };
}

在这个示例代码中,我们首先通过字符串拼接的方式创建了一个包含斐波那契数列计算逻辑的 JavaScript 代码,并使用 Blob 对象将其编译成一个可运行的 JavaScript 文件。然后创建了一个新的 Web Worker,并将编译后的 JavaScript 代码传递进去。最后,我们发送消息给 Worker 并接收计算结果。

需要注意的是,在动态生成 Web Worker 脚本时,我们需要使用 URL.createObjectURL 方法将 Blob 对象转化为 URL 地址,以便于在 Worker 构造函数中加载它。同时,也需要注意在 Web Worker 线程中使用的全局对象不同于主线程,因此无法直接访问主线程中的变量和函数。