for循环异步操作的坑

我们先来看一个实例

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

在这个例子中,我们一般希望输出的值是

0
1
2
3
4
5
6
7
8
9

但实际上,输出的值为10个10。
出现这种情况的原因是因为:每次循环执行后,都会生成一个异步任务,放在一个代码块内,这些任务都会被放入宏队列中进行等待,在js脚本全部运行完后再执行。
我们获得的i值因为是用var定义,在代码块外部并不会被销毁,因此每次拿到的值,实际上是for循环全部执行完成后的最后一个i值(循环头执行了11次,所以i为10)。
那该如何解决这种情况呢?传统的解决方法是放在函数中,立即执行。

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

但这种方法实际上并不便于他人阅读,较为推荐的则是下面的操作

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

因为let在代码块外部会销毁,所以,每个异步任务里拿到的,其实都是自己代码块内部的i,因此可以正常打印

posted @ 2020-11-09 15:34  土狗一号  阅读(195)  评论(0)    收藏  举报