setTimeout( function(){ alert(’你好!’); } , 0); setInterval( callbackFunction , 100);
同理对setInterval的callbackFunction方法每间隔100毫秒就当即被执行深信不疑!
div.onclick = function(){ setTimeout( function(){document.getElementById(’inputField’).focus();}, 0); };
setTimeout( function(){ while(true){} } , 100); setTimeout( function(){ alert(’你好!’); } , 200); setInterval( callbackFunction , 200);
<strong>JavaScript引擎是单线程运行的,浏览器不管在何时都有且只有一个线程在运行JavaScript程序.
</strong>
JavaScript引擎用单线程运行也是有意义的,单线程没必要理会线程同步这些复杂的问题,问题获得简化
那么单线程的JavaScript引擎是怎么配合浏览器内核处理这些定时器和响应浏览器事件的呢?下面结合浏览器内核处理方式简单说明html
浏览器内核实现容许多个线程异步执行,这些线程在内核制控下相互配合以保持同步。假如某一浏览器内核的实现至少有三个常驻线程:javascript引擎线程,界面渲染线程,浏览器事件触发线程,除些之外,也有一些执行完就终止的线程,如Http请求线程,这些异步线程都会产生不一样的异步事件,下面经过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通讯的,虽然每一个浏览器内核实现细节不一样,但这其中的调用原理都是大同小异java
因此,在脚本中执行对界面进行更新操做,如添加结点,删除结点或改变结点的外观等更新并不会当即体现出来,这些操做将保存在一个队列中,待JavaScript引擎空闲时才有机会渲染出来。ajax
同理,仍是在t1时间段内,接下来某个setInterval定时器也被添加了,因为是间隔定时,在t1段内连续被触发了两次,这两个事件被排到队尾等待处理。
若是队列非空,引擎就从队列头取出一个任务,直到该任务处理完,即返回后引擎接着运行下一个任务,在任务没返回前队列中的其它任务是无法被执行的.
相信您如今已经很清楚JavaScript是否可多线程,也理解JavaScript定时器运行机制了,下面咱们来对一些案例进行分析编程
案例1:setTimeout与setInterval浏览器
setTimeout(function(){ /* 代码块... */ setTimeout(arguments.callee, 10); }, 10); setInterval(function(){ /*代码块... */ }, 10);
这两段代码看一块儿效果同样,其实非也多线程
第一段中回调函数内的setTimeout是JavaScript引擎执行后再设置新的setTimeout 定时(此时会把代码插入任务队列),假定上一个回调处理完到下一个回调开始处理为一个时间间隔,理论两个setTimeout回调执行时间间隔>=10ms。setTimeout好处就是严格保证每隔一段时间执行代码。异步
第二段自setInterval设置定时后,定时触发线程就会源源不断的每隔十秒产生异步定时事件并放到任务队列尾,理论上两个setInterval 回调执行时间间隔<=10,这就可能致使上一段代码执行完毕后当即执行下一段代码,不会出现想象中的间隔一段时间再执行编程语言
其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变动时,若是先前已设置回调,这异步线程就产生状态变动事件放到 JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即仍是单线程运行 onreadystatechange所设置的函数.
setTimeout(function(a,b,c){ console.log(a);//a console.log(b);//b console.log(c);//c },0,3,4,5); setInterval(function(a,b,c){ console.log(a);//b console.log(b);//b console.log(c);//c },0,3,4,5);