javascript setTimeout面试题分析

1、题目

<span style="background-color: rgb(255, 255, 255);"><span style="font-size:14px;">/*
*面试官给的原题目如下:
*执行mytest()后,控制台输出内容是_____
*function mytest() {
*    for(var i = 0; i < 5; i ++)
*        setTimeout(console.log(i),0);
*}
*但这应该不是面试官的问题,当时我也没有发现问题,回来测试后才发现,这个函数不是
*面试官要表达的意思。
*/
//正确的代码如下:
function mytest() {
    for(var i = 0; i < 5; i ++)
        setTimeout(function(){
            console.log(i);
        },0);
}</span></span>


2、分析

我的回答是:控制台输出为5 5 5 5 5,虽然答案对了,但是解释就太牵强了,我说是因为for语句之执行速度比setTimeout函数快,面试笑了笑,呜呜~~(这有毛关系)。
后来网上找了一些资料,参考了一些书籍,这里我给出一个靠谱的解释:

首先,我们必须承认,js是单线程的,即使是对于ajax异步方式或者像setTimeout这样的函数。

其次,我们要理解js函数的执行过程,对于setTimeout这样的函数来说并不是每次都能按照预定延迟的时间执行指定函数的。下面举一个列子:

比如有一个函数fun0在执行开始时创建了一个定时器T1,T1定时器将在200ms后被触发指定函数。这时我们需要考虑一个问题,假设fun0的执行时间为250ms(大于200ms),那将会怎样?前面已经说过,js是单线程的,所以不存在fun0和定时器同时执行的情况。这时候定时器制定的函数会在fun0执行完后才执行,定时器的等待时间为250ms,并不是我们指定的200ms。

对于javascript这样的执行方式,我们可以想象在函数执行过程中有两个队列。队列Q1是指执行队列,每次只能执行一个函数;队列Q2就是等待队列,存放着将要执行的函数。每当有一个函数要执行时,就会先把这个函数放进等待队列,如果Q1为空,那么久立即执行这个函数。当然在大多数情况下,函数都是立即执行的。

因此,我们可以知道,setTimeout定时器指定的函数必须要在当前执行队列为空时才会执行。

现在我们再来分析一下上面那道题,很显然,每次的for循环都触发了一个定时函数,这些定时函数有点特殊,是立即执行的(如果执行队列为空的话)。但是在每次触发时,for循环都还未结束,也就是执行队列不为空,此时新建的定是函数只能放在等待队列里无法立即执行。当最后一次for循环执行结束后,执行队列变为空,这时等待队列的函数就立即进入到了执行队列,于是就开始执行只控制台输出。因为setTimeout指定的匿名函数中i的值是一种引用值(自行谷歌脑补),所以输出结果为5 5 5 5 5。


源引:http://www.suchso.com/projecteactual/js-setTimeout-mianshiti.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值