HTML5 Web Workers 多线程

前言

  • 当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。

  • Web Worker 是运行在后台的 JavaScript,不会影响页面的性能。

1、Web Worker

  • Web Worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 Web Worker 在后台运行。

  • 在使用 Web Worker 之前,需检测用户的浏览器是否支持它。

    1
    2
    3
    4
    5
    6
    7
    8
    <script>
    if (typeof (Worker) !== "undefined") {
    // 是的! Web worker 支持!
    // 一些代码.....
    } else {
    // 抱歉! Web Worker 不支持
    }
    </script>

2、创建 Web Worker

2.1 创建 Web Worker 文件

  • 在外部 JavaScript 文件中创建计数脚本,该脚本存储于 “demo_workers.js” 文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var i = 0;

    function timedCount() {
    i = i + 1;
    postMessage(i); // 向 HTML 页面传回一段消息
    setTimeout("timedCount()", 500);
    }

    timedCount();
  • 以上代码中重要的部分是 postMessage() 方法,它用于向 HTML 页面传回一段消息。

  • 注意: Web Worker 通常不用于如此简单的脚本,而是用于更耗费 CPU 资源的任务。

2.2 创建 Web Worker 对象

  • 已经有了 Web Worker 文件,现在从 HTML 页面调用它。

  • 下面的代码检测是否存在 worker 对象,如果不存在,它会创建一个新的 web worker 对象,然后运行 “demo_workers.js” 中的代码。

  • 然后就可以从 Web Worker 接收消息了,向 Web Worker 添加一个 “onmessage” 事件监听器。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <script>
    var w;

    // 检测是否存在 worker
    if (typeof (w) == "undefined") {
    w = new Worker("demo_workers.js");
    }

    // 添加 message 事件监听器
    w.onmessage = function (event) {
    document.getElementById("result").innerHTML = event.data;
    };
    </script>

2.3 终止 Web Worker

  • 创建 Web Worker 对象后,它会继续监听消息(即使在外部脚本完成之后)直到其被终止为止。

  • 如需终止 Web Worker,并释放浏览器/计算机资源,使用 terminate() 方法。

    1
    2
    3
    4
    5
    6
    7
    8
    <script>
    var w;

    function stopWorker() {
    w.terminate(); // 终止 Web Worker
    w = undefined;
    }
    </script>

2.4 完整的 Web Worker 实例代码

  • demo_workers.js 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var i = 0;

    function timedCount() {
    i = i + 1;
    postMessage(i); // 向 HTML 页面传回一段消息
    setTimeout("timedCount()", 500);
    }

    timedCount();
  • index.html 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <!DOCTYPE html>

    <html>
    <head>
    <meta charset="utf-8" />
    <title>Qian Chia 工作室</title>
    </head>
    <body>
    <p>计数: <output id="result"></output></p>

    <button onclick="startWorker()">开始工作</button>
    <button onclick="stopWorker()">停止工作</button>

    <script>
    var w;
    function startWorker() {
    if (typeof (Worker) !== "undefined") {
    if (typeof (w) == "undefined") {
    w = new Worker("demo_workers.js");
    }
    w.onmessage = function (event) {
    document.getElementById("result").innerHTML = event.data;
    };
    } else {
    document.getElementById("result").innerHTML = "抱歉,你的浏览器不支持 Web Workers...";
    }
    }
    function stopWorker() {
    w.terminate();
    w = undefined;
    }
    </script>
    </body>
    </html>
  • 效果

  • 注意:在 Chrome 等浏览器中运行 Web Workers 本地多线程程序时,出现以下错误提示:

    1
    Uncaught DOMException: Failed to construct ‘Worker’:
    • 原因在于 Chrome 不允许通过本地文件访问使用 Web Worker。
    • 解决办法是使用别的浏览器重新进行尝试,或者将程序部署在服务器下,比如 Tomcat。

3、Web Workers 和 DOM

  • 由于 Web Worker 位于外部文件中,它们无法访问下列 JavaScript 对象:

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

4、浏览器支持

  • Internet Explorer 10, Firefox, Opera, Chrome 和 Safari 支持 Web workers。

文章目录
  1. 1. 前言
  2. 2. 1、Web Worker
  3. 3. 2、创建 Web Worker
    1. 3.1. 2.1 创建 Web Worker 文件
    2. 3.2. 2.2 创建 Web Worker 对象
    3. 3.3. 2.3 终止 Web Worker
    4. 3.4. 2.4 完整的 Web Worker 实例代码
  4. 4. 3、Web Workers 和 DOM
  5. 5. 4、浏览器支持
隐藏目录