JS 函数的执行时机

54 阅读1分钟

为什么如下代码会打印 6 个 6


let i = 0
for(i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

原因分析:首先setTimeout是定时器,这个的执行是需要for循环执行完毕之后才执行的,而setTimeout是指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。它在"任务队列"的尾部添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,才会得到执行。因为上面的代码的执行就是:首先给i赋值成为0,这个时候进入循环体发现setTimeout函数,因此就会把这个放到"任务队列"的尾部,循环继续执行,当i的值为6的时候,此时循环条件不满足了,因此循环结束,这个时候就会去执行setTimeout的回调函数,而此时i的值已经变成6了,因此输出的结果就是6个6。

上面代码打印 0、1、2、3、4、5 的方法


for(let  = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}
//输入的结果就是0,1,2,3,4,5

那么有没有其他的方法可以使得输出的结果是0,1,2,3,4,5呢

//利用立即执行函数
let i 
for(i = 0; i<6; i++){ 
    !function(i){ 
        setTimeout(()=>{ 
            console.log(i) 
        },0) 
    }(i) 
}
//利用setTimout的第三个参数,setTimout中的蚕食,第一个表示回调函数,第二个表示的是事件间隔,从
//第三个开始依次用来表示传入回调函数的参数,我们可以利用这一点将每一个i保存下来。

let i
for(i = 0; i<6; i++){
    setTimeout((i)=>{
        console.log(i)
    },0,i)
}