首页 > for循环中setTimeout的问题

for循环中setTimeout的问题

在群里看到的,这方面的知识有点欠缺,希望懂的人可以解答下啊(⊙o⊙)…

for(var i=0;i<10;i++){
  setTimeout((function(i){
   return function(){
       console.log(i);
   }
  })(i),1000);
}
for(var i=0;i<10;i++){
  setTimeout((function(i){
   return function(){
       console.log(i);
   }
  })(i),(function(i){
    return i*1000
  })(i));
}

第一个是循环10次,每次循环执行过程中延迟1秒输出当前i。
第二个也是循环10次,每次执行延迟当前i秒数输出当前i。
应该是这个意思。


第一种方式,setTimeout延迟1000ms才调用里面的函数,0到9很快就能打印出
第二种方式,setTimeout延迟的时间每次都不一样0 ,1000, 2000, 3000, ……所以每隔一秒打印一个数


其他的上面已经說了,建议debugger单步执行,console.log试试,会清晰一点。


闭包吧,去看下闭包相关


首先,执行结果上面的仁兄已经说得很清楚了,第一种方式会在1000ms后很快打印出0至9,第二种方法会在代码执行后每相隔1000ms打印0至9的一个数字。
我们来分析代码:
首先,看这个函数:

(function(i){
   return function(){
       console.log(i);
   }
  })(i)

这样写的作用就是保证每次for循环中执行的setTimeout函数中的i的值都为当前循环时i的值,如果我们这样写:

for(var i=0;i<10;i++){
  setTimeout((function(){
   return function(){
       console.log(i);
   }
  })(),1000);
}

同样也可以正常输出,只是会在1000ms后输出10个10,因为实际上在setTimeout中的函数执行的时候,for循环已经完成了,i的值已经变成了10,当然,我们也可以用es6中的“let”来定义一个块级作用域,就像这样:

for(let i=0;i<10;i++){
  setTimeout((function(){
   return function(){
       console.log(i);
   }
  })(),1000);
}

上面的函数在支持es6语法浏览器中同样会有0到9的输出。

当你理解了(function(i){...})(i)只是为了在function(i)执行的时候i的值能够是当前for循环的i值这个点的时候,第二种方式与第一种方式的区别无非就是根据当前for循环的i值给setTimeout函数添加一个不同的延时罢了,自然也就能理解为什么第二种方式会每隔1000ms输出一个数字了。
建议题主去看一下闭包的相关知识,当然,有兴趣的话,也可以去了解一下“块级作用域”的含义。


两者都是创建10次循环,并且10次循环同时开始计时;
不同的是:第一个循环的10次都是在1s后触发,所以一次性打印出来;
第二个循环的10次每一次比前一次要延迟1s触发,所以打印效果是间隔1s。


谢谢 ,已经明白了

【热门文章】
【热门文章】