当前位置: 首页 > Web前端 > HTML5

WebWorker初体验

时间:2023-04-05 01:11:53 HTML5

Christmas做了一款竞速(戳手指)H5互动小游戏,适合集体活动。在此开发过程中,第一次体验了WebWorker的功能,感觉不错,整理分享。之所以使用它,是因为本次制作的H5互动小游戏需要根据点击速度更新动效,游戏场景元素较多。在使用canvas的过程中,发现在Android机上快速点击后页面卡住。由于动画的卡顿,导致页面的定时器(setInterval)停止,最后安卓机上的游戏最终拖IOS一条街,不科学。本次H5游戏的相关处理不会对主要内容进行处理,可能是处理优化不够导致,请勿深究。分析原因,应该是页面的动画频繁渲染,导致定时器处理事件被阻塞,这也是JavaScript处理单线程的直接结果。于是我就想WebWorker是不是可以解决我的问题,处理定时器的计算呢?JavaScript语言采用单线程模型,即所有任务只能在一个线程上完成,一次只能做一件事。前面的任务还没有完成,后面的任务只能等待。当WebWorker在HTML页面中执行脚本时,页面的状态是无响应的,直到脚本完成。WebWorker是一个运行在后台的JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何您想做的事情:点击、选择等,而WebWorker在后台运行。WebWorker的基本原理是使用Worker类在当前JavaScript主线程中加载一个JavaScript文件来创建一个新的线程,具有非阻塞执行的效果,并提供主线程与主线程之间数据交换的接口。新线程:postMessage,onmessage。所以可以在前台做一些小规模的分布式计算,但是WebWorker有以下限制:WebWorker不能访问DOM节点;WebWorker无法访问全局变量或全局函数;WebWorker不能调用alert()或类似confirm的函数;WebWorker无法访问window、document等浏览器全局变量;使用WebWorker支持检测addEventListener('message',function(e){vardata=e.data;switch(data.cmd){case'start':startTimer();break;case'stop':stopTimer();break;default:break;};},false);vartimerId=null,gameTime=0;varstartTimer=function(){timerId=setInterval(function(){gameTime+=16;varmillion=String(gameTime%1000).substr(0,2);varsecond=String(Math.floor(gameTime/1000));second=second.length>=2?second:'0'+second;self.postMessage({second:second,million:million});},16);}varstopTimer=function(){clearInterval(timerId);gameTime=0;}上面代码的重要部分是postMessage()方法-它用于将消息发送回HTML页面当然,我的应用场景太简单了,webworkers通常不会用于此类一个简单的脚本,但用于更多CPU密集型任务。创建Worker对象if(typeof(Worker)!=="undefined"){letworker=newWorker("./worker.js");}else{alert('doesnotsupportworker')}messageprocessingworker.onmessage=function(event){//接收worker计算相关的数据}webworker传递消息时,会执行事件监听器中的代码.event.data保存来自event.data的数据。错误处理worker.onerror(function(event){//错误处理});终止WebWorkerworker.terminate();后记使用WebWorker后,新开一个线程进行定时器计算,基本解决了游戏时间的问题。由于定时器的间隔时间和发送消息的过程,可能与实际间隔时间还有一些出入,但从活跃度上来说已经在可以接受的范围内了。通过这次WebWorker的简单使用,初步了解了它的基本原理和使用方法,同时也找到了以后类似场景的解决方案。希望对遇到同样问题的朋友有所帮助。