一个web worker就是一个跑在浏览器后台的JavaScript脚本程序;其不会阻塞网页页面的渲染,因为等于是跑在浏览器背后的另外一个进程。两个进程是相对独立的。
Web Worker非常适合高延迟的工作,也是进行并行运算的好工具。因为,它是运行在浏览器背后的独立进程。
下面列出的是各类型浏览器支持HTML Web Worker的最低版本。
API | |||||
---|---|---|---|---|---|
Web Storage | 4.0 | 10.0 | 3.5 | 4.0 | 11.5 |
虽然说不兼容web worker的浏览器都可以去自断经脉了,但出于对极致的追求,在使用web worker前最好还是用代码检测一下浏览器是否支持web worker;具体检测如下代码所示:
if (typeof(Worker) !== "undefined") { // 浏览器支持web worker // 可以干正事了 } else { // 小贼,你的浏览器太落后了,不兼容老夫的web worker呀 }
因为web worker是运行在浏览器背后独立的进程(js进程),所以需要提前准备好用来创建web worker进程的.js脚本文件:
var i = 0; function timedCount() { i = i + 1; postMessage(i); // 把i的值传递给页面主进程 setTimeout("timedCount()",500); } timedCount();
向页面主进程反馈信息:
如上例代码所示,postMessage()
方法的作用就是让“web worker进程”向“HTML页面主进程”发送信息。而HTML页面主进程中的web worker对象则可以通过onmessage事件来获取postMessage发送过来的数据。
一般来说,web worker进程都会需要向页面主进程反馈信息的。
上面已经搞定好了一个web worker外部脚本,现在来看如何在页面主进程中来调用这个web worker工作脚本。(该web worker脚本被命名为“zhuanfou_workers.js”)
如下代码所示,这里做了一个检测,以保证不会重复新建web worker;其实同时创建多个web worker是没问题的,并行就是要多个worker一起干活,但是本例中,以示例为主,会保证只创建1个web worker。
if (typeof(w) == "undefined") { w = new Worker("./static/worker.js"); }
然后看一下该web worker对象是如何通过onmessage来接收web worker进程中postMessage方法发送过来的数据:
w.onmessage = function(event){ document.getElementById("result").innerHTML = event.data; };
当web worker进程发送数据过来时,onmessage方法内的代码就会运行,发送过来的数据会存在event.data内。
Web Worker的工作脚本的url地址必须与主进程页面保持在相同域名下;HTML页面可以引入放在任何第三方站点的js脚本,但是跨域的Web Worker工作脚本是无法被成功加载运行的。
当1个web worker进程在浏览器后台跑起来后,页面主程序就会不断监听其发送过来的信息;如果想要结束这个web worker进程来回收浏览器资源,则可以用terminate
方法:
w.terminate();
上面例子页面主进程中的Web Worker对象就是变量w,如果想重复使用这个变量w,那就在结束该Web Worker进程后,把w变量重新赋值为空,即:
w = undefined;
把上面的每一步联系起来,如下例所示:
<!DOCTYPE html> <html> <body> <p>Web Worker进程发送过来的数据:<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("./static/worker.js"); } w.onmessage = function(event) { document.getElementById("result").innerHTML = event.data; }; } else { document.getElementById("result").innerHTML = "小贼,你的浏览器太落后了,不兼容老夫的web worker呀"; } } function stopWorker() { w.terminate(); w = undefined; } </script> </body> </html>
因为Web Worker是与页面主进程相对独立的进程,因此Web Worker这类外部运行的JS脚本进程是无法调用HTML页面的各种信息,诸如页面的各种HTML元素等。