为什么Koa使用await后还能保持高效

如果你觉得await将原本异步操作变成了同步阻塞的,那你应该对await产生了误解。

事实上,我在早期学习的时候也对 await 有这样的误解,比如说 await setTimeout(XXX, 3000) 会将代码阻塞3秒,相当于Java中的 Thread.sleep(3000)但这个理解是错误的

generator

async/await 是 generator 的语法糖,不用手动调用 next 函数。
先考虑异步操作的特点,最主要的就是注册顺序确定,但执行顺序不确定,就算连续出现多个异步操作,也无法保证他们的回调是顺序运行的。为了控制回调的执行顺序,以往的方法是在回调中注册异步操作,显而易见,这个会造成“回调地狱”,但 generator 中的yield就能有效解决这个问题。

return不同,使用yield能在generator中“返回”多次,比如说有3个 yield,每次调用 next 函数,都会执行到 yield后暂停,直到再次调用 next 函数,在 yield 执行一个异步操作就能以平铺的形式去设置顺序敏感的操作,在每次“返回”之后都能去做其他的事情

await

generator需要调用next函数去继续运行,await 会自动使用 next,无需显式调用,在多个连续的 await 中,每次都会等待本次操作完成后再执行下一个操作,但这并不是同步阻塞的,这里是协程,在异步完成前程序该做什么就做什么,在完成后 await 会获取执行结果,接着运行后面的代码。

所以就算在Controller中使用了 await,比如进行 BCrypt 运算,在运算的过程中,程序依然会正常运行下去,在运算结束拿到结果后才会继续运行下去。