本文将介绍setTimeout()在JavaScript中循环执行时发生的情况。
我们从一段简单的代码出发
let i = 0
for(i = 0; i<6; i++){
console.log(i)
}
在for循环结束时,变量i实际上的值是6,而不是5。为什么呢?
让我们来回顾一下for循环中实际发生的情况:
- 第一遍:
i是1,检查i<6?是的,输出i,执行i++ - 第二遍:
i是2,检查i<6?是的,输出i,执行i++ - 第三遍:
i是3,检查i<6?是的,输出i,执行i++ - 第四遍:
i是4,检查i<6?是的,输出i,执行i++ - 第五遍:
i是5,检查i<6?是的,输出i,执行i++ - 第六遍:
i是6,检查i<6?不是,退出循环。
setTimeout
如果我们希望在输出循环中的每个数字之前先暂停一秒钟怎么办?JavaScript为我们提供了setTimeout方法,我们可以使用此方法来实现。
for(var i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},1000)
}
但是,当执行此代码后,我们会惊讶地发现,输出结果是6 6 6 6 6 6
哇!为什么没有输出1 2 3 4 5 6?
简短的答案是,在for循环执行完成之前,不会触发setTimeout函数回调。在完成for循环之后,setTimeout将使用最终值回调执行。
两种解决方法
那么有什么解决的方法呢?
- 使用let关键字
for(let i = 0;i < 6; i++){
setTimeout(function(){
console.log(i);
}, 1000);
}
- 使用IIFE (Immediately Invoked Function Expression)
for(var i = 0; i < 6; i++){
(function(i){
setTimeout(function(){
console.log( i);
}, 1000);
})(i);
}