HTML5 Web Workers (多线程)


Web worker是在后台运行的JavaScript,不会影响页面的性能.


什么是Web Workers (多线程)?

在HTML页面中执行脚本时,页面将变为无响应,直到脚本完成.

Web worker是一种在后台运行的JavaScript,与其他脚本无关,不会影响页面的性能.您可以继续做任何愿意做的事情: 点击、选取内容等等,而此时 web worker 在后台运行.


浏览器支持

表中的数字指定了第一个完全支持Web Workers的浏览器版本.

API
Web Workers 4.0 10.0 3.5 4.0 11.5

HTML Web Workers示例

下面的示例创建了一个简单的Web worker,它在后台计算数字:

实例

计数:

运行 »

检查Web Worker支持

在创建Web worker之前,请检查用户的浏览器是否支持它:

if (typeof(Worker) !== "undefined") {
    // 您的浏览器支持 Web Workers!
    // Some code.....
} else {
    // 抱歉,您的浏览器不支持 Web Workers..
}


创建Web Worker文件

现在,让我们在外部JavaScript中创建我们的Web worker.

在这里,我们创建了计数脚本.该脚本存储于 "demo_workers.js" 文件中:

var i = 0;

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

timedCount();

上面代码的重要部分是postMessage()方法 - 用于将消息发布回HTML页面.

注意: 通常,Web worker不用于这样的简单脚本,而是用于CPU密集型任务.


创建Web Worker对象

现在我们有了web worker文件,我们需要从HTML页面调用它.

以下行检查worker是否已存在 - 如果不存在 - 它将创建一个新的Web worker对象并运行“demo_workers.js”中的代码:

if (typeof(w) == "undefined") {
    w = new Worker("demo_workers.js");
}

然后我们可以发送和接收来自Web Worker的消息.

向Web worker添加“onmessage”事件侦听器.

w.onmessage = function(event){
    document.getElementById("result").innerHTML = event.data;
};

当web worker发布消息时,将执行事件侦听器中的代码.来自Web worker的数据存储在event.data中.


终止 Web Worker

创建Web工作对象时,它将继续侦听消息(即使在外部脚本完成后),直到它终止.

要终止Web worker并释放浏览器/计算机资源,请使用terminate()方法:

w.terminate();

重用Web Worker

如果将worker变量设置为undefined,则在终止后,可以重用代码:

w = undefined;

完整的Web Worker示例代码

我们已经在.js文件中看到了Worker代码.以下是HTML页面的代码:

实例

<!DOCTYPE html>
<html>
<body>

<p>Count numbers: <output id="result"></output></p>
<button onclick="startWorker()">开始 Worker</button>
<button onclick="stopWorker()">停止 Worker</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>
运行 »

Web Workers和DOM

由于Web worker位于外部文件中,因此他们无权访问以下JavaScript对象:

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

web worker中可以使用什么

前面提到在worker中不能使用window对象和docuemnt对象,那么能够使用什么呢

  • JavaScript的全局对象: JSON、Date()、Array
  • self自身引用
  • location对象,但是其属性都是只读的,改了也影响不到调用者
  • navigator对象
  • setTimeout()、setInterval()及其对应清除方法
  • addEventListener()、removeEventListener()