再谈JavaScript线程


Posted in Javascript onJuly 10, 2015

代码判断一:

<div id="div">
  click me
</div>

<script>
  var div=document.getElementById("div");
  div.addEventListener('click',function(){
   alert('You have clicked me!');
  });
  for(var i =0; i<999999999;i++){
   console.log(i);
  }
</script>

执行之,不出意外的话所有浏览器都会卡死,因为上面的for循环次数太多了,非常耗费CPU资源,而基于JavaScript单线程的事实,浏览器UI渲染被挂起而导致假死。

       现在问题来了,我就是想要实现上述代码,怎么办?

Concurrent.Thread.js
       该类库实质上还是使用setTimeout来实现一个“假的多线程”。在HTML5 WebWorker问世之前是一个很好的选择。比如我们要实现上述“代码片段一”,可以这样写(点我下载类库):

代码片段二:

<div id="div">
  click me
</div>
<script src="Concurrent.Thread.js"></script>
<script>
  Concurrent.Thread.create(function(){
    var div=document.getElementById("div");
    div.addEventListener('click',function(){
     alert('You have clicked me!');
    });
    for(var i =0; i<9999999;i++){
     console.log(i);
    }
  });
</script>

 通过该类库提供的create方法可以创建一个“新线程”。另外,给script标签的type属性设置为 text/x-script.multithreaded-js 也可以实现同样的效果:

代码片段三:

<div id="div">
  click me
</div>
<script src="Concurrent.Thread.js"></script>
<script type="text/x-script.multithreaded-js">
    var div=document.getElementById("div");
    div.addEventListener('click',function(){
     alert('You have clicked me!');
    });
    for(var i =0; i<9999999;i++){
     console.log(i);
    }
</script>

WebWorker
    针对以上浏览器卡死这种糟糕的用户体验,HTML5怎么会熟视无睹呢?

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

代码片段四:

主页面:

<div id="div"></div>
<script>
  window.onload=function(){
     var div=document.getElementById("div");
     if(typeof(Worker)!=="undefined"){//在创建WebWorker之前,先判断浏览器是否支持


  console.log("Start calculating....");
       var time1= new Date()*1;//获得当前时间戳
       var worker=new Worker("fibonacci.js");//创建WebWorker对象,并传递在新线程中将要执行的脚本的路径
       worker.onmessage=function(e){ //监听从新线程发送过来的数据
         div.innerHTML=e.data;
         var time2=new Date()*1;
         console.log("time spend:"+(time2-time1)+"ms");
       }





       worker.postMessage(36);//向新线程发送数据
     }else{
       alert("Your browser do not support WebWoker");
     }
  }
</script>

fibonacci.js:
var fibonacci=function (n){
  return n<3?n:(arguments.callee(n-1)+arguments.callee(n-2));
}
onmessage=function(e){
  var num=parseInt(e.data,10);
  postMessage(fibonacci(num));//向主页面发送数据
}

基本的使用方法已在代码中做注释了,查看控制台,可以看见很快就打印出执行时间了。所以我们得出的结论是:WebWorker适合在前端执行复杂的大量的计算。需要注意的是,WebWorker不支持跨域,本地测试还是用http协议,不要用file协议,否则不能创建Worker对象而报脚本错误 。

再谈JavaScript线程

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

worker.postMessage(36);

    worker.postMessage(36);

    worker.postMessage(36);

       因为此时只有一个WebWorker实例,postMessage会顺序执行而不是异步执行,就不能充分发挥它的性能了。可以通过创建多个WebWorker实例来发送数据。

        需要注意的几点事项有:

        1、我们观察到WebWorker通过接受一个url来创建一个worker,而jsonp的实现原理就是通过动态插入script标签加载数据,那我们尝试用WebWorker来实现同样的事情不是更好吗?因为WebWorker是多线程的,没有阻塞,岂不美哉?但实际上经过实验,我们发现WebWorker表现并不如意。所以这并不是它擅长的事,我们还是不要让它越俎代庖的好。

        2、WebWorker在接受其他来源信息的时候,其实也给站点的安全带来了隐患,如果接收不明来源的脚本信息,可能会导致XSS注入攻击。所以这点需要防范,其实我们上面例子中使用innerHTML是不安全的,可以使用innerText或现代浏览器提供的textContent来替代,以过滤掉html标签。

今天比较累了,想睡觉了,先写这么多吧。

Javascript 相关文章推荐
javascript的对话框详解与参数
Mar 08 Javascript
关于 byval 与 byref 的区别分析总结
Oct 08 Javascript
JavaScript实现在标题栏上显示当前日期的方法
Mar 19 Javascript
JavaScript实现仿网易通行证表单验证
May 25 Javascript
JavaScript判断表单为空及获取焦点的方法
Feb 12 Javascript
JQuery和HTML5 Canvas实现弹幕效果
Jan 04 Javascript
JavaScript纯色二维码变成彩色二维码
Jul 23 Javascript
JavaScript用200行代码制作打飞机小游戏实例
Jun 21 Javascript
jQuery除指定区域外点击任何地方隐藏DIV功能
Nov 13 jQuery
详解JSON Web Token 入门教程
Jul 30 Javascript
详解ES6中的 Set Map 数据结构学习总结
Nov 06 Javascript
tweenjs缓动算法的使用实例分析
Aug 26 Javascript
javascript实现判断鼠标的状态
Jul 10 #Javascript
javascript检查浏览器是否已经启用XX功能
Jul 10 #Javascript
javascript实现确定和取消提示框效果
Jul 10 #Javascript
javascript实现的简单的表单验证
Jul 10 #Javascript
jQuery原生的动画效果
Jul 10 #Javascript
简述Jquery与DOM对象
Jul 10 #Javascript
JavaScript声明变量名的语法规则
Jul 10 #Javascript
You might like
MacOS 安装 PHP的图片裁剪扩展Tclip
2015/03/25 PHP
js 新浪的一个图片播放图片轮换效果代码
2008/07/15 Javascript
js类的静态属性和实例属性的理解
2009/10/01 Javascript
javascript 带有滚动条的表格,标题固定,带排序功能.
2009/11/13 Javascript
TextArea 控件的最大长度问题(js json)
2009/12/16 Javascript
十个优秀的Ajax/Javascript实例网站收集
2010/03/31 Javascript
写给想学习Javascript的朋友一点学习经验小结
2010/11/23 Javascript
ajax上传时参数提交不更新等相关问题
2012/12/11 Javascript
js实现鼠标感应向下滑动隐藏菜单的方法
2015/02/20 Javascript
jquery图片切换插件
2015/03/16 Javascript
js实现的牛顿摆效果
2015/03/31 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
2015/11/24 Javascript
详解iframe与frame的区别
2016/01/13 Javascript
Angular 4依赖注入学习教程之简介(一)
2017/06/04 Javascript
jQuery图片缩放插件smartZoom使用实例详解
2017/08/25 jQuery
JavaScript 自定义事件之我见
2017/09/25 Javascript
VueJs 搭建Axios接口请求工具
2017/11/20 Javascript
关于laydate.js加载laydate.css路径错误问题解决
2017/12/27 Javascript
Python中音频处理库pydub的使用教程
2017/06/07 Python
对Python中type打开文件的方式介绍
2018/04/28 Python
python实现梯度法 python最速下降法
2020/03/24 Python
python读取图像矩阵文件并转换为向量实例
2020/06/18 Python
如何使用amaze ui的分页样式封装一个通用的JS分页控件
2020/08/21 HTML / CSS
大学生毕业自我评价范文分享
2013/11/07 职场文书
办公室经理岗位职责
2014/01/01 职场文书
毕业生个人求职信范文分享
2014/01/05 职场文书
岗位廉政承诺书
2014/03/27 职场文书
国际经济贸易专业自荐信
2014/06/13 职场文书
物流管理专业自荐信
2014/06/23 职场文书
电子信息工程专业自荐书
2014/06/24 职场文书
公司离职证明标准样本
2014/10/05 职场文书
2015年班干部工作总结
2015/04/29 职场文书
乔布斯辞职信(中英文对照)
2015/05/12 职场文书
怎样写观后感
2015/06/19 职场文书
小学四年级班主任工作经验交流材料
2015/11/02 职场文书
vue+springboot实现登录验证码
2021/05/27 Vue.js