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