SOURCE

console.log('script start')
async function async1() {
    await async2()
    console.log('async1 end')
}
async function async2() {
    console.log('async2 end')
}
async1()

setTimeout(function() {
    console.log('setTimeout')
}, 0)

new Promise(resolve => {
    console.log('Promise')
    resolve()
})
.then(function() {
    console.log('promise1')
})
.then(function() {
    console.log('promise2')
})
console.log('script end')

// 解析:

// 打印顺序应该是: script start -> async2 end -> Promise -> script end -> 
// async1 end -> promise1 -> promise2 -> setTimeout

// 老规矩,全局代码自上而下执行,先打印出script start,然后执行async1(),里面先遇到await async2(),执行async2,
// 打印出async2 end,然后await后面的代码放入微任务队列,接着往下执行new Promise,打印出Promise,遇见了resolve,
// 将第一个then方法放入微任务队列,接着往下执行打印出script end,全局代码执行完了,然后从微任务队列中取出第一个微任务执行,
// 打印出async1 end,再取出第二个微任务执行,打印出promise1,然后这个then方法执行完了,当前Promise的状态为fulfilled,
// 它也可以出发then的回调,所以第二个then这时候又被加进了微任务队列,然后再出微任务队列中取出这个微任务执行,
// 打印出promise2,此时微任务队列为空,接着执行宏任务队列,打印出setTimeout。

// 解题技巧:

// 无论是then还是catch里的回调内容只要代码正常执行或者正常返回,则当前新的Promise实例为fulfilled状态。
// 如果有报错或返回Promise.reject()则新的Promise实例为rejected状态。
// fulfilled状态能够触发then回调
// rejected状态能够触发catch回调
// 执行async函数,返回的是Promise对象
// await相当于Promise的then并且同一作用域下await下面的内容全部作为then中回调的内容
// 异步中先执行微任务,再执行宏任务


Promise.resolve().then(()=>{
  console.log('第一个回调函数:微任务11')  
  setTimeout(()=>{
    console.log('第三个回调函数:宏任务22')
  },0)
})
setTimeout(()=>{
  console.log('第二个回调函数:宏任务11')
  Promise.resolve().then(()=>{
    console.log('第四个回调函数:微任务22')   
  })
},0)
// 第一个回调函数:微任务11
// 第二个回调函数:宏任务11
// 第四个回调函数:微任务22
// 第三个回调函数:宏任务22
console 命令行工具 X clear

                    
>
console