浏览器线程与setTimeout(...,0)

clipboard.png

浏览器三个常驻线程

浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程: javascript

javascript引擎线程

javascript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来,而后加以处理,浏览器不管何时都只有一个JS线程在运行JS程序php

GUI渲染线程

GUI渲染线程负责渲染浏览器界面,当页面须要重绘(repaint)或因为某种操做引起的回流(reflow)时,该线程就会执行.可是,须要注意的是GUI渲染线程javascript引擎线程互斥的,当js引擎执行时,GUI线程就会被挂起,GUI更新会被保存在一个队列中,等待js引擎空闲时当即被执行.html

事件触发线程

事件触发线程,当一个事件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其余线程如鼠标点击、AJAX异步请求等,但因为JS的单线程关系全部这些事件都得排队等待JS引擎处理
参考:
JavaScript能否多线程? 深刻理解JavaScript定时机制java


到这里, 就要说另外一个问题, js的异步问题浏览器

setTimeout(...,0)

在js中,咱们经常使用setTimeout(function(){},0)的方式来处理js的异步.
炒个栗子多线程

console.log(1);
setTimeout(function(){console.log(2)},0);
console.log(3);

输出: 1 , 3, 2
不信点我试试
setTimeout(..) 并无把你的回调函数挂在事件循环队列中。它所作的是设 定一个定时器。
当定时器到时后,环境会把你的回调函数放在事件队列中,若是这时候事件循环中已经有 20 个项目了会怎样呢?你的回调就会等待,定时器只能确保你的回调函数不会在指定的 时间间隔以前运行,但可能会在那个时刻运行,也可能在那以后运行,要根据事件队列的 状态而定(PS: 这就是形成定时器不许确的原因)。异步

setTimeout(..0)(hack)进行异步调度,基本上它的意思就是把这个函数插入到当前事件循环队列的结尾处函数


正常状况下javascript都是按照顺序执行的。可是咱们可能让该语句后面的语句执行完再执行自己,先执行全部的同步再执行全部的异步.
炒个栗子spa

for(var i = 0;i < 3;i++){
setTimeout(function(){
alert('知乎');
},0)
alert(i);
}

点我看看
输出: 0 1 2 知乎 知乎 知乎
setTimeout第二个参数为0表示当即执行。当使用这个方法的时候,浏览器会另起一个线程,来执行setTimeout里面的函数,而原有的线程继续执行, 待原有线程结束后,在执行后面的线程(js单线程)。.net

相关文章
相关标签/搜索