HTML5中的Web Worker

来源:互联网 发布:苹果手机文档软件 编辑:程序博客网 时间:2024/06/05 17:20

Web Worker

客户端JavaScript其中一个基本特性就是单线程:比如:浏览器无法同时运行两个事件处理程序,也无法在一个事件处理程序运行的时候触发一个定时器。之所以要设计成单线程是因为:客户端的JavaScript函数必须不能运行太长时间:否则会导致循环事件,web浏览器无法对照用户的输入作出响应。这也就是Ajax的API都是异步的原因。

在Web Wordker标准中,定义了解决客户端无法多线程的问题。其中"Worker"是指执行代码的并并行线程。Web Worker是运行在后台的JavaScript,它不会影响页面的性能,它是独立于其它脚本的,你可以做其它的事情:点击、选取其它内容等操作。Web Worker是运行在后台的。

当在HTML页面中运行脚本时,页面是不可响应的,直到脚本运行结束。

Web Worker标准包含两个部分:第一个部分是Worker对象,该对象是暴露给创建该线程的线程的。第二部分是WorkerGlobalScope:这是一个用来表示新创建的Worker的全局对象,也就是Worker内部要使用的对象


Worker对象

要创建Worker对象,只需使用关键字new后跟Worker构造函数并传入要在Worker中运行的JavaScript脚本的URL路径即可。
var worker = new Worker("js.js");
这是创建了一个Worker对象并立即执行脚本代码,这里的URL可以是绝对路径,也可以是相对路径。

一旦获取Worker对象后,就可以通过postMessage()方法来传递参数了,传递给postMessage()方法的值会"复制",最终的副本会通过message事件传递给Worker(也就是说,传递给Worker的值是一个副本)。

worker.postMessage("file.txt");

可以通过监听Worker对象上的message事件来接收来自Worker的消息。
worker.onmessage = function (e) {    var message = e.data; //data为Worker中的数据,也是postMessage()方法传递的值。};


如果Worker抛出了异常,并且自己没有进行捕获和处理,可以使用error事件来捕获、传递这个异常。
worker.onerror = function (e) {    console.log("这是异常是:" + e.filename + e.message);};

Worker对象也定义了标准的addEventListener()方法removeListener()方法。如果想要管理多个事件处理程序,可以使用这些方法来替代onmessage和onerror事件处理程序。



Worker全局作用域

在通过Worker()构造函数创建一个新的Worker的时候,指定了包含JavaScript代码文件的URL,该代码会运行在一个全新的JavaScript运行环境中,完全和创建Worker的脚本隔离开来的。

WorkerGlobalScope对象也有postMessage()方法和onmessage()事件处理程序,但它们和Worker对象的这两个属性不同的是,使用起来刚好相反:Worker对象中的postMessage()方法会触发Worker对象外部的一个message事件,Worker外部传递的消息会转换成一个事件,并传递给onmessage事件处理程序。WorkerGlobalScope是Worker使用的全局对象,该对象上的postMessage()方法和onmessage属性在Worker代码中,看起来就是全局函数和全局变量。

WorkerGlobalScope对象有全局函数importScript(),该函数是Worker用来加载任何需要的脚本库代码的。也就是说,如果Worker需要使用其它的一个或多个脚本库时,就使用importScript()方法来加载。如下:
//在开始前,先载入需要的类、脚本库等importScript("js1.js", "js2.js", "js3.js");

传入的参数就是需要的脚本库的URL地址。如果载入脚本时出现错误,或者在执行时出现错误,那么剩下的脚本就不会被载入和执行。importScript载入的脚本自身也可以使用importScript()函数来载入其需要的其它脚本。
importScript()是一个同步方法,它必须将所有的脚本 载入并运行完成后 都会返回,一旦importScript返回了就可以使用载入的脚本文件了。


终止Web Worker

一旦创建了Worker对象后,它就会监听消息,直到其被终止。如需终止Web Worker,释放浏览器/计算机资源的话,可以使用terminate()方法
worker.terminame(); //终止 Web Worker



检测是否支持 Worker

在创建Worker对象之前,我们需要浏览器检测一下这个浏览器是否支持Worker。

if (typeof(Worker) !== "undefined") {    //this broswer support     //code} else {    //这个浏览器不支持Worker}


创建一个Web Worker文件

在一个外部JavaScript中创建Web Worker文件。例如这个文件名为"demo_worker.js"。
var i;function timeCount () {    i ++;    postMessage(i); //将副本值传递给worker    setTimeout("timeCount()", 1000);}timeCount();

这是一个计数脚本,postMessage()方法传递的值的副本会传递给Worker,通过onmessage事件处理程序来获取这个消息。


创建Worker对象

在创建这个对象之前,需要检测是否存在这个对象,如果不存在,则创建这个对象。
var worker;if (typeof(worker) !== "undefined") {    worker = new Worker("dome_worker.js");}

然后就可以从Web Worker中发生和接收消息了。

接着为Web Worker添加一个"onmessage"事件处理程序。
worker.onmessage = function (e) {    var message = e.data;};

当Web Worker传递消息时,就会执行事件处理程序中的代码,e.data接收来自Web Worker中的数据。


接下来完整的代码,它用于获取Web Worker中计数:
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Web Worker</title></head><body>    <p>Count number: <output id="result"></output></p>    <button onclick="startWorker()">Start Worker</button>    <button onclick="stopWorker()">stop Worker</button></body><script>    var w;    function startWorker () {        if (typeof(Worker) !== "undefined") { //检测浏览器是否支持worker            if (typeof(w) == "undefined") { //检测worker对象是否存在                w = new Worker("demo_workers.js"); //创建worker对象,并执行worker文件            }            //从web worker发生和接收消息            //向web worker添加一个"onmessage"事件监听器            w.onmessage = function (event) {                document.getElementById("result").innerHTML = event.data; //从事件中获取消息            };        } else {            document.getElementById("result").innerHTML = "your browser does not suppert Web Worker";        }    }    //终止Worker    function stopWorker () {        w.terminate();    }</script></html>

效果如下:





Worker执行模型

Worker线程从上到下 同步 运行它们的代码,然后进入一个异步阶段来对事件以及计时器作出响应。如果Worker注册了onmessage事件处理程序,那么只要message事件有可能触发,那么它们永远不会退出。但是,如果Worker没有监听消息即没有注册onmessage事件处理程序,那么一直到所有任务相关的回调函数都调用以及再也没有任务之后就会退出。一旦所有注册的回调函数 都已经调用之后,Worker再也没有任务了,就会安全退出。


WorkerGlobalScope是Worker的全局对象,因此它也有JavaScript全局对象所拥有的属性,比如:JSON对象、isNaN()函数和Date()构造函数。它还有其它的属性:
  • 计时器方法:setTimeout()、setInterval()、clearTimeout()以clearInterval()。
  • location属性:传递给Worker的URL。它与window下的localtion属性一样。
  • 添加事件处理程序方法:addEventLisener、removeEventLisener。
  • onerror事件处理程序。它描述的是错误的事件处理程序。
  • navigator属性:这个属性与window下的navigator属性一样。




Web Worker知识总结

在HTML页面中运行脚本时,页面是无法响应的,直到脚本执行结束。

Web Worker是运行于后台的JavaScript,它有一个全新的、独立的JavaScript运行环境,与创建Worker的线程是隔离,因此它不会影响页面性能。也就是说,在运行Worker时,我们可以在页面中进行其它操作:选取内容、点击等。

Worker流程:
1、首先要在外部创建一个JavaScript的Worker文件。
2、其次,创建Worker对象。var worker = new Worker("js.js");
3、使用postMessage()方法传递参数,postMessage()方法传递的参数的值是一个副本。
4、postMessage()传递的值会通过message事件传递给Worker。
5、onmessage事件处理程序的event对象的data属性用于获取来自Worker中的消息。
6、terminate()用于终止Worker。


原创粉丝点击