JS的执行顺序

首先我们都知道js是单线程的。

1.什么是单线程?

    通俗点说,就是代码在执行过程中,另一段代码想要执行就必须等当前代码执行完成后才可以进行。我们拿一段代码来解释一下吧

for(var i=1;i<=3;i++){
  setTimeout(function(){
    console.log(i); //输出:4,4,4
  },0)
}

我们来看一下上面的这段代码,既然延时器时间设置为0,那么应该执行一遍循环就应该立即打印出一个i,但是最终的打印结果为:4,4,4。之所以会出现上面的结果,正是因为js代码是单线程应用。在执行过程中,先遇到for循环,for循环先进入线程。当i=1时,循环走到setTimeOut后,此时的for循环还没有执行完成,setTimeOut就会被放入一个地方(线程池)等待执行。此时for循环继续执行,当i=2时,for循环仍没有执行完,这时的setTimeOut仍会被放在线程池中等待执行……依次类推,直到for循环转完3遍后,for循环执行完了,此时线程空闲了,在线程池中等待执行的setTimeOut依次执行打印i,而for循环执行完成后,i变成了4,所以打印出了三个4。

    想改变上面的情况可以用以下两个方法:

//将var变为let,给setTimeOut外套一层块级作用域
for(let i=1; i<=3; i++){
  setTimeOut(function(){
    console.log(i); //输出的结果为1,2,3
  },0);
}
//用自执行函数进行包裹
for(var i=1; i<=3; i++){
  !function(i){
    setTimeOut(function(){
      console.log(i); //输出的结果为1,2,3
    },0);
  }(i)
}

2.promise和setTimeOut

    JavaScript有一个执行栈。在执行代码时,遇到同步任务就放入执行栈中执行,遇到异步任务,如 Ajax   setTimeout 等,就将其放入浏览器的其他模块中去处理。处理完成后将回调函数放入任务队列中,等待执行栈中的任务执行完成后就开始执行。下面以setTimeout为例。

setTimeout(function(){console.log('123')},1000)

浏览器将其放入调用栈后,检测到是异步任务,将其放入其他模块中进行处理,此时计时器开始计时,1000毫秒后将回调函数放入任务队列中,等待调用栈执行完毕后开始执行。当setTimeout和Promise放在一起的时候,由于Promise的任务队列的优先级更高,所以在处理宛调用栈中的任务后,会先处理Promise所在的任务队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值