| |
Web Worker简介
一个Web Worker对象就对应着一个操作系统的线程。使用如下方式创建:var worker = new Worker("foo.js");Worker构造函数的参数是个url,在新建的线程中就执行foo.js中的代码。但是在foo.js中的代码是有限制的,它不能直接访问在主线程也就是html页面中的任何对象,而只能使用消息来进行通信。例如,html中的代码:
var worker = new Worker("foo.js");worker.onmessage = function(e){console.log(e.data);}worker.postMessage("world");foo.js中的代码this.onmessage = function(e){postMessage("hello,"+e.data);}在上述代码中,html中新建一个Worker对象,并监听message事件(也可以使用AddEventListener),最后发送一个"world"字符串给Worker。在foo.js中,监听message时间,当收到来自于主线程的消息时,在消息前面加上"hello,"并回复。
在大多数情况下,都是html页面中的代码发送一个消息给Worker,Worker进行复杂的计算,并且将结果用消息发送给html页面。
不过,postMessage能发送的消息并不能是任意的对象,这个对象不能包含函数,任何dom对象,等等。幸运的是,可以是canvas中的ImageData对象,上面的示例传递的就是ImageData对象。(具体哪些可以,哪些不可以请参考:https://developer.mozilla.org/en/DOM/The_structured_clone_algorithm)
Inline Web Worker
Worker对象构造函数参数一定要是一个url,那如何才能将Web Worker代码和html写在同一个文件中呢?代码如下:function createBlobUrl(text){var bb;if (window.BlobBuilder)bb = new BlobBuilder();else if (window.WebKitBlobBuilder)bb = new WebKitBlobBuilder();else if (window.MozBlobBuilder)bb = new MozBlobBuilder();elsereturn null;bb.append(text);if (window.URL && URL.createObjectURL){return window.URL.createObjectURL(bb.getBlob());}else if (window.webkitURL && webkitURL.createObjectURL){return window.webkitURL.createObjectURL(bb.getBlob());}elsereturn null;}function createInlineWebWorker(id){var url = createBlobUrl(document.getElementById(id).textContent);if (!url) return null;return new Worker(url);}CreateBlobUrl(text)会创建一个url,浏览器访问这个url就会返回text的内容(不过由于chrome一个该死的wontfix的bug,此函数对于保存的本地html不起作用)。试试,复制下面的url,并在浏览器的新页面打开这样就可以这么写了:
<script id="worker1" type="webworker">this.onmessage = function(e){postMessage("hello,"+e.data);}</script><script>var worker = createInlineWebWorker("worker1")</script>注意哦,第一个script的type是worker,所以浏览器并不会执行其代码。而且由于使用script标签,所以中间的内容并不需要html escape也不会显示出来。最后
我来说一下,上面光线追踪中Web Worker代码是怎么写的。Web Worker代码如下:self.onmessage = function(e){var data = e.data;if (data.type=="eval"){var ret;var code = data.code;try{ret = eval(code);}catch(err){postMessage({type:"log",msg:err.message+"\nline:"+err.lineNumber});postMessage({type:"error",msg:err.message+"\nline:"+err.lineNumber});return;}postMessage({type:"result",result:ret});}}很简单吧,就是在Web Worker中运行一下html页面上发过来的代码(不是函数,是代码的文本哦)。如果成功,则将返回值返回给页面;出错则将出错信息返回给页面。例如,你想在Web worker中计算1到100的和,则代码如下:function calc(n){var ret = 0;for (var i=1;i<=n;++i)ret += i;return ret;}worker.onmessage = function(e){if (e.data.type == "result"){alert(e.data.result)}}worker.postMessage({type:"eval",code:calc.toString()+";calc(100);"});好啦,就写到这里啦。其实,我对Web Worker的了解就是参考了google "Web Worker"中第一页的几篇文章,尤其这篇比较通俗易懂:http://www.html5rocks.com/en/tutorials/workers/basics/希望大家能认真看一下。最后的最后,希望下次我能写篇文章来说一下光线追踪的折射。
Web Worker之Milo Yip的光线追踪
TAG: