console.log、setTimeout和Promise的输出顺序

先看题目:你们可以先自己想想,再看答案

console.log(1)
setTimeout(() => {
  console.log(2)
  Promise.resolve().then(() => {
    console.log(3)
  })
});
console.log(4)
new Promise((resolve,reject) => {
  console.log(5)
  resolve()
}).then(() => {
  console.log(6)
  setTimeout(() => {
    console.log(7)
  })
})
console.log(8)

输出结果:

console.log、setTimeout和Promise的输出顺序_第1张图片

 先看结论:

  • 根据js的特性(比如js是单线程),代码有同步和异步之分。
  • js引擎执行整个代码时,若遇到同步代码时,直接执行,若碰到异步代码(setTimeout,Promise.then)时,它不会立即执行这些代码,将异步任务放在任务队列中,等js引擎解析完整个代码后,开始执行任务队列中的的任务。
  • 在异步任务中,又可以分为微任务(如Promise.then)和宏任务(如setTimeout)。
  • 微任务总是在宏任务之前执行。每一个微任务执行完,事件循环会检查微任务队列,如果还有,就继续执行,直到微任务队列为空;在每个宏任务执行完毕后,事件循环会检查微任务队列,并执行所有的微任务,直到微任务队列为空,(这一步是因为有些宏任务中又包含了微任务),然后再继续执行下一个宏任务。这个过程是循环的,直到所有的任务都被处理完毕。

所以js代码执行顺序:同步代码-->异步中的微任务-->异步中的宏任务。这样说有些不严谨,能get到我的意思就行。

特别提醒:js引擎遇到Promise,直接执行Promise中的代码(就像遇到同步代码一样),Promise中的resolve(),reject()会触发then(),then()方法中的回调函数会被添加到微任务队列中等待执行。

回到上面的代码:

console.log(1) //同步:直接执行
setTimeout(() => { //异步中的宏任务,进入任务队列
     console.log(2) 
     Promise.resolve().then(() => {
        console.log(3) //宏任务中包含的微任务,进入微任务队列
      })
    });
console.log(4) //同步:直接执行
new Promise((resolve,reject) => {
    console.log(5) //直接执行
    resolve() // 触发then()
}).then(() => {//异步中的微任务,进入微任务队列
    console.log(6)
    setTimeout(() => {
       console.log(7)//微任务中包含的宏任务,进入任务队列
    })
})
console.log(8)//同步:直接执行

如果本文对你有帮助,希望能得到你的点赞或收藏或关注,这是对我最好的鼓励;

如你有问题或疑惑,欢迎在评论区写下,必将努力解答;

如本文有误区,希望你不吝赐教,让我们共勉!
 

你可能感兴趣的:(javascript)