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

clipboard.png

浏览器三个常驻线程

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

javascript引擎线程

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

GUI渲染线程

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

事件触发线程

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


到这里, 就要说另一个问题, 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都是按照顺序执行的。但是我们可能让该语句后面的语句执行完再执行本身,先执行所有的同步再执行所有的异步.
炒个栗子

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值