HTML5 Web Workers是一种在浏览器后台运行JavaScript代码的方式,它允许开发者在不阻塞主线程的情况下执行复杂的计算任务。Web Workers可以处理一些耗时的操作,如图像处理、大量数据的计算等,从而提高网页的性能和响应速度。
一、Web Workers示例
下面的例子创建了一个简单的 Web Workers,在后台计数:
<!DOCTYPE html> <html> <body> <p>计数: <output id="result"></output></p> <button onclick="startWorker()">开始 Worker</button> <button onclick="stopWorker()">停止 Worker</button> <br /><br /> <script> var w; function startWorker() { if(typeof(Worker)!=="undefined") { if(typeof(w)=="undefined") { w=new Worker("/example/html5/demo_workers.js"); } w.onmessage = function (event) { document.getElementById("result").innerHTML=event.data; }; } else { document.getElementById("result").innerHTML="Sorry, your browser does not support Web Workers..."; } } function stopWorker() { w.terminate(); } </script> </body> </html>
二、Web Worker支持
在创建 web worker 之前,请检测用户浏览器是否支持它:
if (typeof(Worker) !== "undefined") { // 是的!支持 Web worker! // 一些代码..... } else { // 抱歉!不支持 Web Worker! }
这种方式可以有效地确保您的应用程序在不支持Web Worker的浏览器上也能够正常运行,并且在支持Web Worker的浏览器上充分利用其提供的后台计算能力。
三、创建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 worker 后,它会继续监听消息(即使在外部脚本完成后)直到其被终止为止。如需终止 web worker,并释放浏览器/计算机资源,请使用 terminate() 方法:
w.terminate();
六、复用Web Worker
如果把 worker 变量设置为 undefined,在其被终止后,可以重复使用该代码:
w = undefined;
七、完整的Web Worker代码
完整的Web Worker代码示例:
<!DOCTYPE html> <html> <body> <p>Count numbers: <output id="result"></output></p> <button onclick="startWorker()">Start Worker</button> <button onclick="stopWorker()">Stop Worker</button> <br><br> <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 = "Sorry! No Web Worker support."; } } function stopWorker() { w.terminate(); w = undefined; } </script> </body> </html>
八、Web Worker和DOM
Web Workers 是在浏览器中运行的后台脚本,它们在自己的全局上下文中执行,与主线程中的全局上下文分开。由于这种分离,确实存在一些限制,无法直接访问以下对象:
1、window 对象: 在 Web Worker 中无法直接访问 window 对象,因为它代表了浏览器窗口的一个实例,而 Web Worker 运行在后台,并没有直接的窗口实例。
2、document 对象: 同样地,由于 document 对象代表了当前载入的 HTML 文档,而 Web Worker 运行在后台并不直接操作 DOM,所以无法直接访问 document 对象。
3、parent 对象: 在 Web Worker 中也无法直接访问 parent 对象,因为它通常用于访问包含 iframe 的父窗口,而 Web Worker 并不直接涉及页面结构和嵌套窗口。
九、浏览器支持
下面表格中的数字指示完全支持 Web Worker 的首个浏览器版本:
浏览器 | IE | Firefox | Safari | Opera | |
版本 | 4.0 | 10.0 | 3.5 | 4.0 | 11.5 |