for循环内setTimeout顺序输出的解法
let i = 0
for(i = 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
上面那段代码按常规理解会输出0,1,2,3,4,5,但实际输出6个5。主要原因是由于for循环在主线程内,setTimeout是异步方法,在任务队列里面,只有主线程执行完后,任务队列才执行,此时i的值已经是5,所以得到结果是个6个5,以下有几种解决方法
- 第一种,将let i放在循环中进行创建,这样就可以每次循环创建一个块变量i,且变量i只能作用于这个块中
···
for(let i= 0; i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
··· - 第二种,将 i 作为setTimeout的参数进行传入
let i = 0
for(i = 0; i<6; i++){
setTimeout((i) => console.log(i),1000,i);
}
- 第三种,使用闭包
let i = 0
for(i = 0; i<6; i++){
setTimeout(
(i =>
() => console.log(i)
)(i), 0);
}
- 第四种,用立即执行函数进行包裹
let i = 0
for(i = 0; i<6; i++){
!function(i) {
setTimeout(()=>{
console.log(i)
},0)
}(i)
}