乐趣区

关于javascript:await-的执行顺序

之前看 koa 文档是 koa 是洋葱模型,外面用到的 await,next。话不多说,间接贴图吧

理论 await 就是这样的执行逻辑。
先看一段代码:

      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 紧跟前面的被阻塞的代码

再看一段联合 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,列为宏 3

所以 setTimeout 的执行程序就是:
time2–>timer3–>timer1

退出移动版