标签:des style blog http color io os 使用 java
可以从下面的代码中看到,第一个用setTimeout中的代码是死循环,由于是单线程,下面的两个定时器就没机会执行了。
<script type="text/javascript"> setTimeout( function(){ while(true){} } , 100); setTimeout( function(){ alert(‘你好!setTimeout‘); } , 200); setInterval( function(){ alert(‘你好!setInterval‘); } , 200); </script>
浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现3个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。
由上图可看出,浏览器中的JavaScript引擎是基于事件驱动的,这里的事件可看作是浏览器派给它的各种任务,JavaScript引擎一直等待着任务队列中任务的到来,由于单线程关系,这些任务得进行排队,一个接着一个被引擎处理。
t1、t2....tn表示不同的时间点,tn下面对应的小方块代表该时间点的任务。
t1时刻:
浏览器事件触发线程:
在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成一个鼠标点击事件,由图可知,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标点击事件正在等待处理。定时触发线程:
这里的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就计不了时,它必须依赖外部来计时并触发定时,所以队列中的定时事件是异步事件。ajax异步请求:
浏览器新开一个http线程请求,当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到JavaScript引擎的处理队列中等待处理。1)未使用setTimeout函数
在网上找到的一段代码实例,这里用来演示一下。
<a href="#" id="doBtn">do something</a> <div id="status"></div> <script type="text/javascript"> var doBtn = document.getElementById(‘doBtn‘) , status = document.getElementById(‘status‘); function sleep(ms) { var start = new Date(); while (new Date() - start <= ms) {} } doBtn.onclick = function(e) { status.innerHTML = ‘doing...please wait...‘; sleep(3000); // 模拟一个耗时较长的计算过程,3s status.innerHTML = ‘done‘; return false; }; </script>
我在firefox中执行了上面的代码。计划是点击“do something”按钮,然后显示“doing...please wait...”,接着执行sleep,最后显示“done”。
但是结果是点击后,浏览器卡住3秒左右,最后直接显示done。
分析下看出,在做status.innerHTML设置的时候,是需要执行GUI渲染线程的,但是现在还在执行JavaScript引擎线程,而JavaScript引擎线程与GUI渲染线程是互斥的,所以就最后显示了done。
2)使用了setTimeout函数
<a href="#" id="doBtn2">do something timer</a> <div id="status2"></div> <script type="text/javascript"> var doBtn2 = document.getElementById(‘doBtn2‘) , status2 = document.getElementById(‘status2‘); function sleep2(ms) { var start = new Date(); while (new Date() - start <= ms) {} } doBtn2.onclick = function(e) { status2.innerHTML = ‘doing...please wait...‘; setTimeout(function() { sleep2(3000); status2.innerHTML = ‘done‘; }, 100); return false; }; </script>
在“doing...please wait...”后面加了个setTimeout,延时执行,给了浏览器渲染的时间,这个时候会显示出“doing...please wait...”的字样,然后执行sleep函数,最后显示“done”。
demo下载:
http://download.csdn.net/download/loneleaf1/7955393
http://ejohn.org/blog/how-javascript-timers-work/ How JavaScript Timers Work
http://heroicyang.com/2012/08/28/javascript-event-loop/ JavaScript Event Loop 浅析
http://www.2cto.com/kf/201204/129337.html JavaScript可否多线程?
http://www.nowamagic.net/librarys/veda/detail/787 优化js脚本设计,防止浏览器假死
http://www.ruanyifeng.com/blog/2013/10/event_loop.html 什么是 Event Loop?
标签:des style blog http color io os 使用 java
原文地址:http://www.cnblogs.com/strick/p/3972526.html