JavaScript中的Web worker多线程API研究
HTML5支持了WebWorker这样的API,允许网页在安全的情况下执行多线程代码。不过WebWorker实际上受到很多限制,因为它无法真正意义上共享内存数据,只能通过消息来做状态通知,所以甚至不能称之为真正意义上的“多线程”。
WebWorker的接口使用起来很不方便,它基本上自带一个sandbox,在沙箱中跑一个独立的js文件,通过postMessage和onMessge来和主线程通信:
varworker=newWorker("my.js"); varbundle={message:'Helloworld',id:1}; worker.postMessage(bundle);//postMessage可以传一个可序列化的对象过去 worker.onmessage=function(evt){ console.log(evt.data); //比较worker中传回来的对象和主线程中的对象 console.log(bundle); //{message:'Helloworld',id:1} }
//inmy.js onmessage=function(evt){ vardata=evt.data; data.id++; postMessage(data);//{message:'Helloworld',id:2} }
得到的结果可以发现,线程中得到的data的id增加了,但是传回来之后,并没有改变主线程的bundle中的id,因此,线程中传递的对象实际上copy了一份,这样的话,线程并没有共享数据,避免了读写冲突,所以是安全的。保证线程安全的代价就是限制了在线程中操作主线程对象的能力。
这样一个有限的多线程机制使用起来是很不方便的,我们当然希望Worker能够支持让代码看起来具有同时操作多线程的能力,例如,支持看起来像下面这个样子的代码:
varworker=newThreadWorker(bundle/*sharedobj*/);
worker.run(function(bundle){ //dosthinworkerthread... this.runOnUiThread(function(bundle/*sharedobj*/){ //dosthinmainuithread... }); //... });