关于setTimeout()函数

for( var i = 1; i < 10; i++ ){
    setTimeout( function(){
        colsole.log(i);
    }, i * 1000);
}

我能理解为什么最后输出的全是10, 但是我不能理解为什么是1秒1次;求解答?

按我的理解,应该是第一次1秒,第二次2秒,,依次下去

阅读 5.6k
8 个回答

应该是几乎同时设置了9个setTimeout, 而不是每秒钟设置一个setTimeout,所以造成了第一个1s后2s的事件刚好触发

0s 1 2 3
1s 触发 -- --
2s -- 触发 --
3s -- -- 触发

因为你是近乎同时设置了9个分别延时1s,延时2s,延时3s......延时9s,执行console.log(10)的函数,明白了吗?

setTimeout(function(){},time)就是给一个函数设置定时器,当成一个方法来用,你在循环里面调用,就相当于调用了十次,然后同时执行,然后一秒完了就变成两秒三秒那样,如同一楼说的一样!如果要实现你说的那样,必须让他们加上上一个定时器时间才会出现你要的效果

实现方法:
var i = 0;
var timer = setInterval(function () {
    console.log(i);
    if (i === 9) {
        clearInterval(timer);
    }
    i++;
}, 1000)

相关知识:

setTimeout()和setInterval()函数都是设置一个定时器,并返回给定时器的ID。

setTimeout(函数f, 1000);是在等待1秒后执行函数f,只执行一次,序列如下:

1. 等待1秒
2. 执行函数f

setInterval(函数f, 1000);重复执行等待1秒 + 函数的指令,序列如下:

while (true)
    1. 等待1秒
    2. 执行函数f

setTimeout 是异步的,当你执行第一个console的时候 i 已经增加到10了。异步与闭包的问题

for循环瞬间就执行完了,此时10个定时器函数都被加到了事件队列中,第一个等待1秒执行了,此时第二个定时器也已经过了一秒,再过1s就执行第二个了,以此类推。

题主想实现递增执行的话,可以通过将所有的任务加入数组,然后通过reduce函数来实现!

经典js问题,面试官最喜欢了!

for( var i = 1; i < 10; i++ ){ 
  (function(i) {
    setTimeout( function(){ 
                console.log(i); 
          }, i * 1000); 
  })(i);
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏