一 async await
- await 1.对promise求值;2.阻塞当前程序,等待结果
- async 1.配合await使用;2.使函数返回promise
二 koa 特点
- Koa是Node.js的一个开发框架,其最大的特点是精简和强大的中间件。
- 在Koa中,一切的流程都是中间件,数据流向遵循洋葱模型,先入后出,是按照类似堆栈的方式组织和执行。
- 洋葱模型
来源:白话koa2的洋葱模型
1.一个请求一旦到后端,就开始接触洋葱的最外层。
2.遇到一个next(),就进入下一层。不过值得提醒的是,异步函数的next(),与同步函数的next(),不是在同一个空间的,我们可以假想一个“异步空间栈”,后入先出。
3.什么时候到洋葱中心?就是遇到的第一个没有next的中间件,或者遇到一个中间件报错,就会把这个中间件当成中心,因为遇到错误了,不会再继续往里面走。这个时候,就开始向洋葱的外层开始走了。如果第一个中间件就没有next,直接返回的。那么就不存在洋葱模型。
4.一层一层外面走的时候,就先走位所有的同步中间件,再依次走“异步空间栈”的中间件。
- 实例化的应用程序对象 有多个中间件
- 注册中间件,中间件本质就是个函数,接收前端发来的http请求,就需要用到中间件
- 永远只自动执行第一个中间件 第二个及之后 用参数next()执行
- 中间件next()返回是Promise
- 上下文ctx (Context),可用作中间件之间传值。
ctx.req:Node 的 request 对象.
ctx.res:Node 的 response 对象.
ctx.request:koa 的 Request 对象.
ctx.response:koa 的 Response 对象.
const Koa = require('koa')
const app = new Koa()
app.use((ctx, next) => {
console.log(1)
const a = next() // 返回Promise
console.log(2)
console.log(ctx.r)
})
app.use((ctx, next) => {
console.log(3)
next()
console.log(ctx.r)
console.log(4)
})
app.use(async (ctx, next) => {
console.log(5)
const axios = require('axios')
const res = await axios.get('https://www.baidu.com')
ctx.r = res
next()
console.log(6)
})
app.listen(3000)
为什么 async await ???
- 有人说使用async await是为了让每个中间件都返回Promise,这种说法是错误的,next()本身就返回 Promise,这是koa本身就具有的特性
- 真正原因是为了保证洋葱模型的执行顺序,中间件必须用async await,例如前两个中间件没有使用,第三个因为有接口请求,就不能保证在执行完第三个中间件之后再打印4
为什么 洋葱模型 ???
-
如上示例,假如第一个中间件要拿到第三个中间件的res,简单的可以用return,一次返回到第二个中间件,第一个中间件,但前提条件是这些中间件都是自己编写的,假如第二个中间件是第三方的,那么返回到第二个中间件,我们不可能改写第三方的代码,致使第一个中间件拿不到res。
-
用上下文ctx传值,第三个中间件把res存到ctx中,因为axios使代码异步执行,如果不能保证洋葱模型,那么在第二个中间件是拿不到res的。
所以,必须保证洋葱模型!!!
const Koa = require('koa');
const app = new Koa();
// logger
app.use(async (ctx, next) => {
await next();
const rt = ctx