手机版

再谈JavaScript线程

时间:2021-09-09 来源:互联网 编辑:宝哥软件园 浏览:

代码判断1:

div id='div '单击me/div script var div=document . getelementbyid(' div ');div.addEventListener('click ',function(){ alert('您已经单击了我!');});for(var I=0;i999999999I){ console . log(I);}/script,没有任何意外,所有浏览器都会卡住,因为上面for循环太多,消耗CPU资源。但是基于JavaScript是单线程的事实,浏览器UI渲染被挂起,导致了假死。

现在问题来了,我只想实现上面的代码。我该怎么办?

并发。Thread.js这个类库本质上是用setTimeout实现了一个“假多线程”。在HTML5 WebWorker出现之前是一个不错的选择。比如我们要实现上面提到的“代码片段一”,可以写如下(点击我下载类库):

代码片段2:

div id='div '单击me/div script src=' http : concurrent。Thread.js'/scriptscript并发。thread . create(function(){ var div=document . getelementbyid(' div ');div.addEventListener('click ',function(){ alert('您已经单击了我!');});for(var I=0;i9999999I){ console . log(I);} });/script可以通过这个类库提供的create方法创建一个“新线程”。此外,将script标签的type属性设置为text/x-script .多线程-js可以达到同样的效果:

代码片段三:

div id='div '单击me/div script src=' http : concurrent。thread . js '/script script type=' text/x-script .多线程-js ' var div=document . getelementbyid(' div ');div.addEventListener('click ',function(){ alert('您已经单击了我!');});for(var I=0;i9999999I){ console . log(I);}/scriptWebWorker html 5怎么能对以上浏览器被卡住的不良用户体验视而不见呢?

让我们用经典的斐波那契数列来测试:

代码片段4:

主页:

div id=' div '/div script window . onload=function(){ var div=document . getelementbyid(' div ');if(工人类型)!=='undefined'){//创建WebWorker前,判断浏览器是否支持console.log('开始计算.');var time1=新日期()* 1;//获取当前时间戳varworker=new worker(' Fibonacci . js ');//创建一个WebWorker对象,并传递要在新线程中执行的脚本的路径。worker . on message=function(e){//侦听新线程发送的data div . innerhtml=e . data;var time2=新日期()* 1;console . log(' time spend : '(time 2-time 1)' ms ');} worker . postmessage(36);//将数据发送到新线程} else {alert('您的浏览器不支持webwoker ');} }/script Fibonacci . js:var Fibonacci=function(n){ return n3?n :(arguments . calleer(n-1)arguments . calleer(n-2));} on message=function(e){ var num=ParSeint(e . data,10);postMessage(Fibonacci(num));//将数据发送到主页面}代码中已经标注了基本的使用方法。看控制台,可以看到执行时间很快就会打印出来。因此,我们得出结论,WebWorker适合在前端执行大量复杂的计算。需要注意的是,WebWorker不支持跨域,仍然使用http协议进行本地测试,不使用文件协议,否则无法创建Worker对象并报告脚本错误。

如果我们需要连续执行多个postMessage操作,最好不要一直写work.postMessage,如下所示:

worker . postmessage(36);worker . postmessage(36);worker . postmessage(36);此时只有一个WebWorker实例,postMessage将按顺序执行,而不是异步执行,因此无法充分利用其性能。您可以通过创建多个WebWorker实例来发送数据。

有几点需要注意:

1.我们观察到web workers通过接受url来创建worker,jsonp的实现原理是通过动态插入脚本标签来加载数据。我们尝试使用网络工作者来实现同样的事情不是更好吗?如果WebWorker是多线程的,不阻塞,岂不是很美?但实际上,通过实验,我们发现WebWorker的性能并不令人满意。所以这不是它擅长的,所以我们不应该让它接手。

2.当WebWorker收到其他来源的信息时,实际上给网站的安全带来了隐患。如果他们从未知来源收到脚本信息,可能会导致XSS注射攻击。因此,有必要对此加以防范。事实上,在我们上面的例子中使用innerhtml是不安全的。相反,我们可以使用现代浏览器提供的内部文本或文本内容来过滤掉HTML标签。

我今天累了。我想睡觉。先写这么多。

版权声明:再谈JavaScript线程是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。