当在HTML 页面中执行脚本时,页面会变得没有响应直到脚本执行完成。

当在HTML 页面中执行脚本时,页面会变得没有响应直到脚本执行完成。
web worker是在后台运行的JavaScript,独立于其他脚本,不会影响页面的性能。你可以继续执行你想做的任何事情:点击,选取等等,同时web worker就在后台运行。
一个简单的示例:创建一个简单的web worker,在后台计数
计数:
开始创建一个web worker前,首先要检查浏览器是否支持:
if (typeof(Worker) !== "undefined") { // Yes! 支持Web Workers! // ... } else { // Sorry! 浏览器不支持Web Workers... }
因为实例化Worker对象的时候需要传入要执行的JavaScript文件名,所以我们需要在外部创建一个 JavaScript 文件:
var i=0; function timedCount() { i=i+1; postMessage(i); setTimeout("timedCount()", 500); } timedCount();
下面的代码创建了一个新的web worker 对象,如果指定的JavaScript文件存在的话,浏览器会生成一个新的worker线程,"worker.js"文件文件被异步下载,其中的代码被运行。
var worker = new Worker("worker.js");
Worker是通过message事件和页面通信的,来自Worker的数据保存在event.data中。
在下面的代码中,我们给web worker 对象添加了一个"onmessage"事件监听器。
worker.onmessage = function (event) { var data = event.data; // 对数据进行处理 document.getElementById("result").innerHTML=data; };
在Worker 内部调用postMessage()就可以发送消息到页面。
var i=0; function timedCount() { i=i+1; postMessage(i); setTimeout("timedCount()", 500); } timedCount();
在所有支持的浏览器中,postMessage()都能支持对象参数,也就是说可以序列化为JSON结构的任何值都可以作为参数传递给postMessage()。
<button onclick="sayHI()">Say HI</button> <button onclick="unknownCmd()">Send unknown command</button> <button onclick="stop()">Stop worker</button> <output id="result"></output> <script> function sayHI() { worker.postMessage({'cmd': 'start', 'msg': 'Hi'}); } function stop() { // Calling worker.terminate() from this script would also stop the worker. worker.postMessage({'cmd': 'stop', 'msg': 'Bye'}); } function unknownCmd() { worker.postMessage({'cmd': 'foobard', 'msg': '???'}); } var worker = new Worker('worker.js'); worker.addEventListener('message', function(e) { document.getElementById('result').textContent = e.data; }, false); </script>
self.addEventListener('message', function(e) { var data = e.data; switch (data.cmd) { case 'start': self.postMessage('WORKER STARTED: ' + data.msg); break; case 'stop': self.postMessage('WORKER STOPPED: ' + data.msg + '. (buttons will no longer work)'); self.close(); // Terminates the worker. break; default: self.postMessage('Unknown command: ' + data.msg); }; }, false);
web worker 对象创建以后,直到被终止掉之前会一直监听有没有消息(即使外部的脚本已经执行完成)。
我们可以使用terminate() 方法来终止一个web worker, 同时释放浏览器和计算机资源。
// 立即停止worker 的工作 worker.terminate();
在Worker 内部,调用close()方法也可以停止工作。就像在页面中调用terminate()方法一样,Worker停止工作后就不会有事件发生了。
// Web Worker 内部的代码 self.close();
// 页面 的内部代码,发送数据给worker worker.postMessage(data);
// Web Worker 的内部代码 self.onmessage = function(event) { var data = event.data; //......各种数据处理 self.postMessage(data); // 把数据再发回给页面 }
由于web worker 多线程的特点,web worker 只能访问JavaScript的一些特性:
Worker不能访问:
Worker 内部的 JavaScript 在执行过程中碰到错误时就会触发error事件。
error 事件的三个属性:
worker.onerror = function(event) { console.log("ERROR: " + event.filename + " (" + event.lineno + "): " + event.message); }
凡是比较消耗时间的操作,都可以转交给Worker来做而不会阻塞用户界面
Web Workers 标准目前在W3C的状态是Candidate Recommendation(2012/05/01),还在继续制定和改进之中。