await 的执行顺序

以前看koa文档是koa是洋葱模型,里面用到的await,next。话很少说,直接贴图吧

实际await就是这样的执行逻辑。
先看一段代码:promise

async function async1() {
        console.log("async1 start");
        await async2();
        console.log("async1 end");
      }
      async function async2() {
        console.log("async2");
        await async3()
      }
      async function async3() {
        await async4()
        console.log('async3')
      }
      async function async4() {
        await async5()
        console.log('async4')
      }
      async function async5() {
        console.log('async5')
      }
      async1();
      console.log('start')
      // 执行结果
      // async1 start
      // async2
      // async5
      // start
      // async4
      // async3
      // async1 end

分析下为什么是这样的:
前面执行结果其实都很容易写出来
async1 start
async2
碰见await async2,那么紧跟在await async2 后面的那些代码就会延迟执行了。
有人说,由于await是promise的语法糖,因此实际紧跟await后面的代码能够理解成
new Promise().then(的回调函数来执行)
鹅,,,多是这样的,或许这样也好记好理解一些。
仍是按照洋葱模型来理解执行顺序吧。
第一个await async2 后面的代码先放着,一会再回来执行
ps:何时再回来执行呢?
答曰:等到没有遇到新的await后,而且非await的同步代码也执行完了后。
因此执行顺序是:
await async2 --> await async3 --> await async4 --> await async5
-->执行非await的同步代码
-->反过来执行await async5紧跟后面的被阻塞的代码
...
-->反过来执行await async2紧跟后面的被阻塞的代码koa

再看一段结合setTimeout异步的代码异步

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
  setTimeout(() => {
    console.log('timer1')
  }, 0)
}
async function async2() {
  setTimeout(() => {
    console.log('timer2')
  }, 0)
  console.log("async2");
}
async1();
setTimeout(() => {
  console.log('timer3')
}, 0)
console.log("start")
// 执行结果
// 'async1 start'
// 'async2'
// 'start'
// 'async1 end'
// 'timer2'
// 'timer3'
// 'timer1'

这里setTimeout都延迟了0秒,因此按照eventLoop的宏任务,按照宏队列循环的前后来执行。
执行await async2()时,内部有一个timer2的setTimeout,因此列为宏1,
执行同步代码时候,碰见一个timer3的setTimeout,列为宏2,
按照await紧跟在后面的代码的洋葱执行逻辑,timer1,列为宏3async

因此setTimeout的执行顺序就是:
time2-->timer3-->timer1函数

相关文章
相关标签/搜索