再看JavaScript线程
继上篇讨论了一些关于JavaScript线程的知识,我们不妨回过头再看看,是不是JavaScript就不能多线程呢?看下面一段很简单的代码(演示用,没考虑兼容问题):
代码判断一: <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对象而报脚本错误
。
如果我们需要连续执行多个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标签。
今天比较累了,想睡觉了,先写这么多吧。有兴趣深入了解的同学可以查看这个地址了解更多知识:深入了解HTML5工作线程
再看JavaScript线程的更多相关文章
- 再看GS线程
再看GS线程 void GameServer::ProcessThreadTry() { ; packet rcvPkt; rcvPkt.data = * ]; //该事件工厂主要创建了两个定时器1. ...
- 再看javascript执行上下文、变量对象
突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文.变量对象.作用域.this等语言细节.内容短小而精悍,文风直白而严谨,读完有酣畅淋漓 ...
- setTimeout setInterval 区别 javascript线程解释
原文:http://www.iamued.com/qianduan/1645.html 今天看到这篇文章,学到了不少东西 特此发出来 和大家分享 JavaScript的setTimeout与setIn ...
- javascript线程解释(setTimeout,setInterval你不知道的事)---转载
在工作中,可能我们经常遇到在有很多 setInterval 的页面, 再手动触发 setTimeout 的时候经常失败, 尤其是 jquery做动画的时候,一些渐入溅出的东西,很多东西都不被触发……, ...
- javascript线程解释(setTimeout,setInterval你不知道的事)
john resig写的一篇文章: 原文地址:http://ejohn.org/blog/how-javascript-timers-work/ 作为入门者来说,了解JavaScript中timer的 ...
- JavaScript线程
JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如 setTimeout( ...
- [从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)【转】
(function(){ //这里忽略jQuery所有实现 })(); 半年前初次接触jQuery的时候,我也像其他人一样很兴奋地想看看源码是什么样的.然而,在看到源码的第一眼,我就迷糊了.为什么只有 ...
- Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service
原文:Android菜鸟的成长笔记(17)-- 再看Android中的Unbounded Service 前面已经写过关于startService(Unbounded Service)的一篇文章:&l ...
- Javascript:看 Javascript 规范,学 this 引用,你会懂的。
目录 背景this待分析程序先看一个语言规范方法调用备注 背景返回目录 Javascript 的 this 是我的心病,多数情况下知道其运行结果,个别变态的场景下,就给不出解释了,昨天一次偶然的机遇让 ...
随机推荐
- echarts 折线柱形上方显示自定义格式数据
series:[ { name: '成单率', type: 'line', data: valueArr2, itemStyle: { normal: { label: { show:true, po ...
- 在Java项目中整合Scala
Scala是一个运行在Java JVM上的面向对象的语言.它支持函数编程,在语法上比Java更加灵活,同时通过Akka库,Scala支持强大的基于Actor的多线程编程.具有这些优势,使得我最近很想在 ...
- [Whole Web] [AngularJS] Localize your AngularJS Application with angular-localization
It is best to start your application's localization efforts early in development, even if you only s ...
- webstrom热键[持续更新]
1.Ctrl+ Shift + A -- 为了加快寻找菜单命令或工具栏操作,你并不需要看菜单.只有按Ctrl+ Shift + A(说明|查找操作主菜单上),并开始输入动作的名称. . 2.Ctr ...
- ajax技术的基本概述
大家都知道ajax并非一种新的技术,而是几种原有技术的结合体.它由下列技术组合而成. 1.使用CSS和XHTML来表示. 2. 使用DOM模型来交互和动态显示. 3.使用XMLHttpRequest来 ...
- cglib源码分析(三):Class生成策略
cglib中生成类的工作是由AbstractClassGenerator的create方法使用相应的生成策略完成,具体代码如下: private GeneratorStrategy strategy ...
- html5标签兼容ie6,7,8
注册博客园已经三年了,这三年一直在忙,没时间写博文.也许是忙,也许是懒吧!当然这三年发生了很多事,我也从开发人员转变为前端人员. 是时候对所学的,所用的知识做一下沉淀了.就从这一篇开始吧! html5 ...
- 小巧、高效、美观的弹出日历组件 ——lhgcalendar
http://www.cnblogs.com/lhgstudio/archive/2009/02/13/1390381.html 没法上传附件,请到以上地址下载 下载地址:http://files.c ...
- JS调用PHP 和 PHP调用JS的方法举例
http://my.oschina.net/jiangchike/blog/220988 1.JS方式调用PHP文件并取得PHP中的值举一个简单的例子来说明:如在页面test_json1中用下面这句调 ...
- c#md5与SHA1验证函数
/// <summary> /// MD5验证函数 /// </summary> /// <param name="fileName">文件的路 ...