HTML5之Worker用法
HTML5提供了Worker类用于多线程处理。Worker是在UI主线程中创建,后台执行的一段js脚本,它通过消息与UI线程传递数据。使用Worker就3步:
cheungmine 2011-11-29
第1步:创建一个Worker,需要指定一个js文件,作为Worker线程的执行体:
var worker = new Worker("worker.js");
第2步:给Worker实例指定消息处理函数,只有2个:onmessage ,onerror
worker.onmessage = function (event) {
// update UI here
var t1 = new Date().getTime();
elemById("_time").value = t1 - t0;
elemById("_piValue").value = event.data;
};
worker.onerror = function (event) {
alert(event.message);
};
第3步:给worker发消息:postMessage。
elemById("_time").value = "-";
t0 = new Date().getTime();
worker.postMessage(parseInt(elemById("_num_rects").value));
下面以一个具体的例子来说明Worker的用法。这个例子是用数值积分的方法求pi=(3.1415926....)的。worker.js就是做这个工作。
// worker.js
// calculate pi using numerical integration
// 2011-11, cheungmine
self.onmessage = function (event) {
// numerical integration to calc pi
var num_rects = event.data;
var width = 1.0/num_rects;
var mid;
var height;
var sum = 0.0;
var area;
for (var i=0; i<num_rects; i++) {
mid = (i+0.5) * width;
height = 4.0/(1.0+mid*mid);
sum += height;
}
area = width*sum; // area=pi
// post message back to UI thread
self.postMessage(area);
};
HTML5主页面js-test.html如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js-test.html</title>
<script type="text/javascript">
function elemById(id) {
return document.getElementById(id);
}
function getBrowserAgent() {
var browser = "$";
if ((navigator.userAgent.indexOf('MSIE') >= 0) &&
(navigator.userAgent.indexOf('Opera') < 0)){
browser = "$IE";
}
else if (navigator.userAgent.indexOf('Firefox') >= 0){
browser = "$FIREFOX";
}
else if (navigator.userAgent.indexOf('Opera') >= 0){
browser = "$OPERA";
}
else if (navigator.userAgent.indexOf('Chrome') >= 0){
browser = "$CHROME";
}
return browser;
}
var browser = getBrowserAgent();
window.addEventListener('load',
function () {
if (browser=="$IE") {
// MSIE
if (window.confirm("IE does not support HTML5 currently.\n"+
"please use lastest FireFox, Chrome or Opera!\n"+
"if you havenot any of them installed,\n"+
"please click OK to enter download page.")) {
window.location.replace("selbrowser.html");
}
else {
window.close();
}
}
else if (browser=="$FIREFOX"||browser=="$CHROME") {
// do stuff for FireFox and Chrome
}
else {
// do stuff for others
}
initPage();
},
false
);
var dt = new Date();
var t0 = 0;
function initPage () {
// onclick
elemById("_piWorker").addEventListener('click',
function(){
var worker = new Worker("worker.js");
worker.onmessage = function (event) {
// update UI here
var t1 = new Date().getTime();
elemById("_time").value = t1 - t0;
elemById("_piValue").value = event.data;
};
worker.onerror = function (event) {
alert(event.message);
};
elemById("_time").value = "-";
t0 = new Date().getTime();
worker.postMessage(parseInt(elemById("_num_rects").value));
},
false
);
}
</script>
</head>
<body>
<p>Press button "calc" to get pi</p>
<p>
<input type="input" size="10" id="_num_rects" value="100000000">
<input type="button" id="_piWorker" value="calc">
pi=<input type="input" size="30" id="_piValue" value="">
time elapsed: <input type="input" size="10" id="_time" value="-">
</p>
</body>
</html>
如果用户不小心用IE打开了主页面,我们需要提示用户目前IE还干不了这个活,下面的是下载支持HTML5的浏览器页面selbrowser.html:
<html>
<head>
<title>selbrowser.html</title>
</head>
<body>
<p><h4>Download the lastest HTML5 browser!</h4></p>
<table align="center">
<tr>
<td width="200"><a href="http://www.mozilla.org/en-US/firefox/all.html"><h3>Mozilla FireFox</h3></a></td>
<td width="200"><a href="http://www.google.cn/chrome/eula.html?hl=zh-CN&platform=win"><h3>Google Chrome</h3></a></td>
<td width="200"><a href="http://www.opera.com/download/"><h3>Opera</h3></a></td>
</table>
</body>
</html>
好,全齐了。把上面3个文件放到同一个目录如:C:/myJSP/test下面:
test/js-test.html
test/worker.js
test/selbrowser.html
使用FireFox直接打开file:///C:/myJSP/test/js-test.html即可。目前FireFox8不支持http://localhost:8080/myJSP/test/js-test.html,会报Could not load domain错误。
但是FireFox Aurora支持,只是Worker计算速度超慢。
目前Chrome不支持Worker直接用file:///C:/myJSP/test/js-test.html方式打开,会报Uncaught Error: SECURITY_ERR: DOM Exception 18。
可以使用Chrome以http://localhost:8080/myJSP/test/js-test.html方式打开。需要建一个本地http server,如tomcat。
Opera两种方式都支持。