JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序

一、浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。

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

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

3. 事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。(当线程中没有执行任何同步代码的前提下才会执行异步代码)

看下这段代码,setTimeout是异步线程,需要等待js引擎处理完同步代码(while语句)之后才会执行,while语句直接是个死循环,js引擎没有空闲,不会执行下面的alert,也不会插入setTimeout。所以即使这个时候你把setTimeout的时间改成0,他还是不会执行。看下实例:

setTimeout(function(){ console.log(123); var s = new Date(); var n = s.getTime(); console.log(n); },0)

for (var i = 0; i < 50; i++) { console.log(new Date().getTime()); };

执行结果如下:

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596750 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

1387784596765 VM257:9

undefined

123 VM257:3

1387784596765

也就是说即使setTimeout为0,他也是等js引擎的代码执行完之后才会插入到js引擎线程的最后执行。

在看一下如果有多个异步插入线程的情况:

setTimeout(function(){

console.log(1);

var s = new Date();

var n = s.getMilliseconds();

var t = s.getTime();

console.log(n);

console.log(t);

console.log(1);

},1000)

setTimeout(function(){

console.log(2);

var s = new Date();

var n = s.getMilliseconds();

var t = s.getTime();

console.log(n);

console.log(t);

console.log(2);

},500)

setTimeout(function(){

console.log(3);

var s = new Date();

var n = s.getMilliseconds();

var t = s.getTime();

console.log(n);

console.log(t);

console.log(3);

},0)

for (var i = 0; i < 1000; i++) {

if(i == 0){

console.log(new Date().getTime());

}

console.log(new Date().getMilliseconds());

if(i == 999){

console.log(new Date().getTime());

}

};

1387793158633 VM655:31

43633 VM655:33

125648 VM655:33

135664 VM655:33

314679 VM655:33

293695 VM655:33

90711 VM655:33

1387793158711 VM655:35

undefined

VM655:21

711 VM655:25

1387793158711 VM655:26

VM655:27

VM655:12

132 VM655:16

1387793159132 VM655:17

VM655:18

VM655:3

631 VM655:7

1387793159631 VM655:8

VM655:9

1387793158711-1387793158633

78

1387793158633+500

1387793159133

1387793158633+1000

1387793159633

在for循环中执行了1000次打印,时间到1387793158711,setTimeout时间为0的开始执行,过了498毫秒,setTimeout为500的开始执行,再过998毫秒,setTimeout为1000的开始执行。为什么会差2毫秒,我也没搞懂。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值