setTimeOut运行机制详解

今天刷牛客网上的一道题

for(var i=0;i<5;++i){
setTimeout(function(){
   console.log(i+ ’ ’);
},100);
}

问运行结果是什么。

之前我想当然的认为肯定是0,1,2,3,4啊,然而真的不是想当然的。这里考察的是setTimeout的异步运行。

这段程序可以理解为:匿名函数根本就没有立即执行。正因为没有立即执行,所以在循环的过程中,匿名函数没有及时访问到每一个变量,这样外部函数循环完成之后,匿名函数才执行开始访问外部函数的变量,而这时变量的值早已成为最后一个。所以最后的结果是5,5,5,5,5。


想要出现0,1,2,3,4,很简单,给匿名函数传入参数即可。

for(var i=0;i<5;++i){
setTimeout(function(){
console.log(i+ ’ ’);
}(i),100);
}
直接是()也行……
for(var i=0;i<5;++i){
setTimeout(function(){
console.log(i+ ’ ’);
}(),100);
}
结果都可以,于是我就想啊,这个setTimeOut到底是怎么个运行机制呢?

众所周知,setTimeout定时器时用来产生异步执行的效果的,也就是异步事件。
js是单线程的语言,如果前一个任务耗时很长,后一个任务就不得不一直等着。有时候,前一个任务的cpu是在空闲着,这时想要充分利用cpu缩短任务执行时间,可以

挂起处于等待中的任务,先运行排在后面的任务。等到前一个任务返回了结果,再回过头,把挂起的任务继续执行下去。

这样,js可以分为主线程和任务队列,用来完成异步任务。

具体来说,异步执行的运行机制如下。(同步执行也是如此,因为它可以被视为没有异步任务的异步执行。)

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)主线程之外,还存在一个"任务队列"(taskqueue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。


任务队列,是个事件的队列(也可以理解成消息的队列),IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有哪些事件。

当主线程上的任务都执行完了,就从任务队列中依次取事件来执行。


上述题是的var i变量在主线程上,所以会先执行了i,等i都执行完之后,才会将任务队列中的回调函数取出来执行,所以最后的结果是5,5,5,5,5,。

加上参数的意思是给这个回调函数传入参数,相当于形成了块级作用域,使得匿名函数能在for这个块级中自己执行,所以能在for循环的时候执行,也就是说能在循环的同时传入参数,结果是0,1,2,3,4。(其实还是有点不太理解………………)

          欢迎各位大牛批评指正……

参考文章:http://blog.csdn.net/qingwenxiutong/article/details/52397676


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值