Computing with JavaScript Web Workers
一点体会:
以前对于大计算量的应用为了使得界面不至于僵死,只有将任务分成子任务,用timeout 来分批运行 ,其根本原因是 javascript本质是单线程的 ,集中时间大计算量的话会使得界面失去响应 ,更常用的是 将任务传到server端快速运行,利用xhr读取server端结果 。
09-09-01:
setTimeout 方式只是相当于模拟了多线程,而不是真正的多线程,比如当今的多核处理器,真正的多线程可以利用运行在不同的core而真正并行执行加快运行效率,这种timeout模拟的方式就不行了哦,只能在一个core运行的。
如今最新的浏览器 firefox 3.5 为我们提供了新的计算方式:
Worker ,后台运行的一段javascript ,突破了javascript的单线程模式,但是worker不可以动用界面操作,同java swing类似,界面操作仍然要单线程,worker 通过消息传递,将结果传给主线程,只有主线程才能进行界面操作,实现UI和处理线程分离。
举个例子:
两个文件 : html ,javascript(worker.js) 。由html中javascript 传递消息给worker
调用端:
<h1>请用 firefox 3.5 运行</h1>
<p>由于 javascript 的单线程特性,以前计算量很大的话就要放在server端运行,利用xhr回调取的结果,
<br/><br/>
现在也可以在client 后台运行了 ,界面不会僵死,但是 worker 不能进行界面dom操作,界面操作单线程保证
<br/>
</p>
<button id="test" > 后台worker运行 </button>
<button id="test2" > 当前线程运行 </button>
<div id="status" style="border:1px green solid;margin:10px;height:100px;color:red;">
</div>
<script type="text/javascript">
//将要后台运行的一段代码
var worker = new Worker("worker.js");
//后台worker返回的结果
worker.onmessage = function(ev){
document.getElementById("status").innerHTML="后台worker计算完毕:结果:<br />" +ev.data;
}
document.getElementById("test").onclick=function(){
alert("后台worker将要进行 1 ~ 1000000000 的遍历 ,但是界面不会僵死,点确定后等一会后台worker会返回信息");
document.getElementById("status").innerHTML="后台worker计算中 .....";
//将消息发给后台计算,主界面仍然可以操作,不会僵死
worker.postMessage(1);
};
document.getElementById("test2").onclick=function(){
document.getElementById("status").innerHTML="";
alert("当前线程运行将要进行 1 ~ 1000000000 的遍历 ,点确定后,界面将要僵死");
for(var i=0;i<1000000000;i++);
document.getElementById("status").innerHTML="当前线程 计算完毕:结果:<br /> 2";;
};
</script>
后台 worker.js :
//得到主线程传过的消息 onmessage = function(ev){ for(var i=0;i<1000000000;i++); //将结果传递给主线程,注意不可以进行界面操作,不可以访问主线程页面数据,只能访问消息数据 postMessage( "来自 worker " + (parseInt(ev.data)+1) ); };
09-09-01:
上面所说的 xhr 实际上就是 web worker ,只不过它具有不同的特定任务的socket API (from even faster websites)