for循环中执行setTimeout问题
代码片段:
for(var i=0;i<8;i++){
setTimeout(function () {
console.log(i)
},0)
}
输出了8次8,这跟js的执行顺序和作用域链有关。
1、js同步执行与异步执行
js的执行机制: js是单线程环境,从上到下、依次执行,即 同步执行;在这段代码中,for循环是同步代码,setTimeout是异步代码。
js在执行代码的过程中,碰到同步代码会依次执行,碰到异步代码就会将其放入任务队列中进行等待,当同步代码执行完毕后再开始执行异步代码,即 异步执行。
2、js作用域问题
当同步代码执行完毕后,开始执行异步的setTimeout代码,执行setTimeout时需要从当前作用域内寻找一个变量 i ,此时for循环已执行完毕,当前 i=8,所以执行setTimeout时输出为8,任务队列中的剩余7个setTimeout也依次执行,输出为8。
3、常用解决方法
利用立即执行函数,当for循环执行时,就会立即执行setTimeout,从而使得到的每个副本i值都不一样,这样就可以得到想要的for循环的结果。如:
for(var i=0;i<8;i++){
(function (x) {
setTimeout(function () {
console.log(x)
},0)
})(i);
}