之前看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