当前位置主页 > 资料库 > 前端教程 > HTML5教程 | HTML5 Web Workers

HTML5教程 | HTML5 Web Workers

08-27

HTML5 Web Workers可以让WEB应用程序具备后台处理的能力。它对多线程的支持非常好,因此,使用了HTML5的javascript应用程序可以充分利用多核CPU带来的好处。

Web Workers API能够异步和自主的处理javascript文件。一个web worker就是一个处理javascript文件的线程。我们可以将耗时较多的任务分配给HTML5 Web Workers API来处理,这样可以避免弹出脚本运行画面的对话框等等。

虽然Web Workers是否强大,但它也不是万能的,有些事情它也无能为力。例如在Web Workers中执行的脚本不能访问这个页面的window对象(window.document)。也就是说,Web Workers不能直接访问Web页面和DOM API。虽然Web Workers不会导致浏览器UI停止响应,但是仍然会消耗CPU周期,导致系统响应缓慢。

创建一个Web Worker

在使用Web Workers API之前,要先检查一下浏览器是否支持它。

function isSupportWebWorkers() {
  if(typeof(worker) != 'undefined') {
    document.geElementById('support').innerHTML = "你的浏览器支持 HTML5 Web Workers!";
  }
}                            
                            

你可以通过下面的代码来创建一个Web Worker:

var worker = new Worker("assets/worker.js");   
                            

传入Worker()方法中的参数是一个要执行的JavaScript文件的URL地址。

和HTML5 Web Workers通信

你可以使用HTML5 Messaging API来和Web Worker进行通信。通过postMessage API可以传送和接收数据。postMessage API还可以跨框架和跨窗口进行通信。大多数的javascript对象都可以通过postMessage进行传送,但是含有循环引用的除外。下面是一段示例代码:

var worker = new Worker("assets/worker.js");

worker.onmessage = function(event) {
    alert("Reply: " + event.data);
}

worker.postMessage("Hello worker!");                              
                            

在上面的代码中,首先创建了一个Worker对象。然后在这个Web Worker上添加了onmessage事件监听函数,这个函数会在创建它的页面发送信息时被调用。最后,通过worker.postMessage()方法将信息发送给Web Worker。

Web Worker的响应信息应该类似下面的样子:

this.onmessage = function(event) {
    postMessage("Reply from web worker");
}                              
                            

这段代码是Web Worker执行的javascript代码的一部分。this关键字指向的是Web Worker自己。在这个Web Worker上被添加了一个onmessage事件监听。它和前面在页面中创建一个Web Worker并添加onmessage事件监听是不一样的,虽然它们都是在Web Worker对象实例上添加监听事件。Web Worker通过postMessage()来响应信息。

交互JSON数据

在前面的Web Workers的例子中,浏览器在交互信息时使用的是字符串。如果你想传送JSON对象,你可以使用JSON.stringify()方法来将一个JSON对象进行编码,然后使用JSON.parse()方法来进行解码。

在Mozilla MDN上提供了一种新的方法来交换数值或JSON对象,具体请参考:The structured clone algorithm

完整的Web Workers实现

下面是一段完整的web worker实现代码:

this.onmessage = function(event) {

    postMessage("Reply from web worker");

}

//Implementation of web worker thread code
setInterval(function() { runEveryXSeconds() }, 5000);

function runEveryXSeconds() {
    postMessage("Calling back at : " + new Date().getTime());
}                              
                            

这个web worker实现消息的监听,以及开启动它之后每5秒钟向页面发送一条信息。

Web Worker示例

下面的示例是上面的代码的具体实现。你可以点击下面的按钮来执行这个Web Worker:

要停止Web Worker没5秒钟向页面发送一次信息,可以刷新一次页面。

Web Worker的应用和局限

正如前面所提到的,Web Workers并不是万能的。Web Workers在使用中会有一些限制。

一个Web Worker不能访问创建它的页面的DOM元素。

下面列出了一些可以在Web Worker脚本中执行的操作:

  • 使用onmessage时间来监听消息。
  • 使用postMessage()函数来发送消息。
  • 使用XMLHttpRequest来发送AJAX请求。
  • 使用setTimeout()setInterval()来创建定时器。
  • Web Sockets。
  • Web SQL Databases
  • Web Workers
  • 使用importScripts()来导入更多的js脚本。
在Web Worker中导入javascript脚本

你可以使用importScripts()函数来在Web Worker导入javascript脚本来使用。importScripts()是一个非常特别的Web Worker函数,下面是一个例子:

importScripts("myscript.js");
importScripts("script1.js", "script2.js");                             
                           

通过importScripts()函数你可以导入一个或多个js脚本。脚本的加载是同步的,它们会同时被执行。

共享Web Worker

一个Web Worker只能被创建它的页面使用。如果你想在多个页面之间共享一个Web Worker,可以使用SharedWorker。一个SharedWorker可以被同源(相同域名)的所有页面访问。

创建SharedWorker

你可以像下面这样创建一个SharedWorker

var worker = new SharedWorker("shared-worker.js");                             
                           

传入SharedWorker对象的参数是要被执行的js文件的路径字符串。

在所有的页面中都创建一个以相同URL作为参数的SharedWorker,这将使得它们都连接到同一个SharedWorker上。

连接一个SharedWorker

SharedWorker中有一个概念叫端口,各种引用了SharedWorker的页面可以通过它联系起来。

下面是一个如何在SharedWorker端口中监听消息的例子:

var worker = new SharedWorker("/html5/web-worker-shared.jsp");

worker.port.addEventListener("message",
        function(event) {
            alert(event.data);
        }
        , false
);

worker.port.start();                             
                           

上面的代码首先创建了一个SharedWorker,然后在这个SharedWorker的端口上添加事件监听,最后启动这个端口。如果你不启动它,你就不能向SharedWorker发送消息。

向一个SharedWorker发送消息

当端口被启动之后,你的页面就会在这个端口上监听消息。你可以通过port.postMessage()函数来向SharedWorker发送消息。下面是一个示例代码:

worker.port.postMessage("First Message");                             
                           
一个SharedWorker的完整实现

一个SharedWorker和普通的Web Worker一样,需要在JavaScript文件中实现它的功能。下面是一个比较完整的实现代码:

var ports = [] ;

onconnect = function(event) {

    var port = event.ports[0];
    ports.push(port);
    port.start();

    port.addEventListener("message",
        function(event) { listenForMessage(event, port); } );
}


listenForMessage = function (event, port) {
    port.postMessage("Reply from SharedWorker to: " + event.data);
}

//Implementation of shared worker thread code
setInterval(function() { runEveryXSeconds() }, 5000);

function runEveryXSeconds() {
    for(i = 0; i < ports.length; i++) {
        ports[i].postMessage("Calling back at : "
                + new Date().getTime());
    }
}                             
                           

上面的代码首先创建了一个数组来存储所有连接SharedWorker的页面的端口。

接着定义了一个onconnect函数,这个函数会在一个页面和SharedWorker连接时被调用。

onconnect函数先获得连接页面的端口,并将它存储在端口数组中,然后启动端口。最后,onconnect函数在端口上添加一个消息监听。这里要注意他为每一个连接页面创建了一个匿名函数。这个匿名函数会捕捉连接页面的端口,并将它作为参数传入到listenForMessage()函数中。

接下来定义了一个listenForMessage()函数,这个函数使用一串简单的字符串来响应接收到消息的端口。

最后,在SharedWorker中设置了一个定时器,每5秒钟执行一次runEveryXSeconds()函数。

runEveryXSeconds()函数简单的迭代所有的连接端口,并向它们发生一条消息。

上面的代码只是一个最简单的实现。一个高级的实现可以从服务器上获取数据,并将数据分布到所有连接到SharedWorker的页面中。

一个SharedWorker例子

下面是一个SharedWorker的例子。你可以点击按钮来启动SharedWorker。然后通过右边的按钮来向SharedWorker发送信息。

返回HTML5教程目录
Previous:
上一篇:HTML5教程 | HTML5元素拖放
Next:
下一篇:HTML5教程 | HTML5语义元素
返回顶部