2011-06-07 11:58:02| 分类: javascript | 标签: |举报 |字号大中小 订阅
写得透彻的javaS
JavaS
setTimeout( function(){ alert(’你好!’); } , 0);
setInterval( callbackFunction , 100);
认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaS
同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不疑!
但随着JavaS
div.on
setTimeout( function(){document.getElementById(’inputField’).focus();}, 0);
};
既然是0毫秒后执行,那么还用setTimeout干什么, 此刻, 坚定的信念已开始动摇.
直到最后某一天 , 你不小心写了一段糟糕的代码:
setTimeout( function(){ while(true){} } , 100);
setTimeout( function(){ alert(’你好!’); } , 200);
setInterval( callbackFunction , 200);
第一行代码进入了死循环,但不久你就会发现,第二,第三行并不是预料中的事情,alert问候未见出现,callbacKFunction也杳无音讯!
这时你彻底迷惘了,这种情景是难以接受的,因为改变长久以来既定的认知去接受新思想的过程是痛苦的,但情事实摆在眼前,对JavaS
拔开云雾见月明
出现上面所有误区的最主要一个原因是:潜意识中认为,JavaS
而事实上的,JavaS
JavaS
JavaS
那么单线程的JavaS
下面结合浏览器内核处理方式简单说明.
浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假如某一浏览器内核的实现至少有三个常驻线 程:javas
?
由图可看出,浏览器中的JavaS
上图t1-t2..tn表示不同的时间点,tn下面对应的小方块代表该时间点的任务,假设现在是t1时刻,引擎运行在t1对应的任务方块代码内,在这个时间点内,我们来描述一下浏览器内核其它线程的状态.
t1时刻:
GUI渲染线程:
该线程负责渲染浏览器界面HTML元素,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行.本文虽然重 点解释JavaS
在JavaS
所以,在脚本中执行对界面进行更新操作,如添加结点,删除结点或改变结点的外观等更新并不会立即体现出来,这些操作将保存在一个队列中,待JavaS
GUI事件触发线程:
JavaS
定时触发线程:
注意这里的浏览器模型定时计数器并不是由JavaS
由图可知,在这t1的时间段内,继鼠标点击事件触发后,先前已设置的setTimeout定时也到达了,此刻对JavaS
同理, 还是在t1时间段内,接下来某个setInterval定时器也被添加了,由于是间隔定时,在t1段内连续被触发了两次,这两个事件被排到队尾等待处理.
可见,假如时间段t1非常长,远大于setInterval的定时间隔,那么定时触发线程就会源源不断的产生异步定时事件并放到任务队列尾而不管它 们是否已被处理,但一旦t1和最先的定时事件前面的任务已处理完,这些排列中的定时事件就依次不间断的被执行,这是因为,对于JavaS
t1过后,也就是说当前处理的任务已返回,JavaS
如果队列非空,引擎就从队列头取出一个任务,直到该任务处理完,即返回后引擎接着运行下一个任务,在任务没返回前队列中的其它任务是没法被执行的.
相信您现在已经很清楚JavaS
案例1:setTimeout与setInterval
setTimeout(function(){
/* 代码块... */
setTimeout(arguments.callee, 10);
}, 10);
setInterval(function(){
/*代码块... */
}, 10);
这两段代码看一起效果一样,其实非也,第一段中回调函数内的setTimeout是JavaS
案例2:ajax异步请求是否真的异步?
很多同学朋友搞不清楚,既然说JavaS
其实请求确实 是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaS
评论