koa2框架
- koa2框架是原生支持async/await的
async/await的简单示例
- 回顾以前使用Promise的例子:使用Promise的例子
- 通过以前的例子来对比使用使用Promise和使用async/await:
- 在async函数中,使用await我们可以获取到Promise对象成功时传递的数据,也可使用 try-catch 截获promise 中reject 的值:
async/await 要点
更多基础知识可参考笔记ES6 async函数与await关键词
- await后面可以追加promise 对象,获取resolve()传递的值
- await必须包裹在async 函数里面使用
- 执行 async 函数返回的也是一个promise 对象
- 可使用 try-catch 截获promise 中reject 的值
安装koa2框架
(所有安装都可加上淘宝镜像 --registry=https://registry.npm.taobao.org
来加速)
- 安装脚手架工具koa-generator:
npm install koa-generator -g
- 注意:这里是koa,没有2,因为它也可用于1版本的
- 初始化koa2项目:
koa2 项目名
- 进入项目目录下,安装package.json中的所有依赖:
npm install
- 由于package.json中缺少全局环境参数,所以手动安装一个:
npm i cross-env --save-dev
- 安装完成后需要修改package.json:
- **运行项目(热更新)**:
npm run dev
(package.json中显示已经有nodemon,所以无需重新添加,直接使用即可) - 由package.json的dev可知项目运行先执行的是启动server的文件bin/www,原本端口为3000,现将端口设置为8000:
- 重新运行项目后测试:
项目目录分析
- app.js:
- 各个插件的作用
- 思考各个插件的实现原理(结合之前学过的知识)
- 处理get请求和past请求
介绍路由
router.get()
:定义处理get请求的路由- 参数1:路由url
- 参数2:async函数,路由符合时做的事情
router.post()
:定义处理post请求的路由- 参数1:路由url
- 参数2:async函数
- 注意:
- router来自中间件’koa-router’
- 定义路由后需要在app.js中引入路由并使用**
app.use()
注册路由**
ctx.render()
是渲染的页面ctx.body
是返回的内容ctx.params
:对象,其中包含路由中传递的参数- 比如:通过路由获取的参数userName
ctx.request.body
:对象,其中包含post请求中的数据- 用自带的路由举例:
- 对应页面:
处理GET请求的路由
新建博客路由(router.get())
routes下新建blog.js:
app.js中注册路由(app.use())
app.js中引入并使用博客路由:
测试
- 没用框架的时候,query部分需要我们自己从req的url中的字符串提取query部分后,再使用querystring的parse()将字符串转换为JS对象,现在可以直接得到query对象
处理POST请求的路由
新建用户路由(router.post())
routes下新建user.js:
app.js中注册路由(app.use())
app.js中引入并使用博客路由:
postman测试
注意是json格式的数据:
ctx.request.body
- **
ctx.request.body
**中的内容为: - **
ctx.request
**中的内容为:- 可以看到,我们通过
ctx.body
返回的数据,框架已经将格式定为json,就不需要我们手动使用stringify()设置了。
- 可以看到,我们通过
中间件机制
- 洋葱圈模型:中间件之间通过next函数联系,当一个中间件调用 next() 后,会将控制权交给下一个中间件, 直到下一个中间件不再执行 next() 后, 将会沿路折返,将控制权依次交换给前一个中间件。
app.use()
注册中间件
- 注册中间件 语法:
app.use()
- 参数1:路由地址,可省略,省略则所有路由都匹配
- 参数2:中间件,中间件必须返回async函数
- async函数的参数1:ctx
- ctx包括了req和res
- 可通过
ctx.request.body
获取到req中的数据 - 可通过
ctx.query
获取get请求时?
后面是数据(框架会自动将其转换为JSON对象,使用=
、&
分隔)
- async函数的参数2:next
- async函数返回的是Promise对象
- async函数的参数1:ctx
- 参数3:(可选)中间件,
app.use()
中可有多个中间件,顺序执行- 使用方法:中间的中间件在外部定义 命名async函数,然后在
app.use()
中调用该函数,最后的中间件使用匿名函数直接书写。 - 一般最后一个中间件是主函数,前面的中间件做验证,比如登录验证,如果前面的中间件就发现密码不对则当即停止,不需要继续往下执行
- 使用方法:中间的中间件在外部定义 命名async函数,然后在
中间件
- 中间件:
app.use()
的参数2就是中间件 - 中间件必须返回async函数
- async函数的参数1:ctx
- ctx包括了req和res
- 可通过
ctx.request.body
获取到req中的数据 - 可通过
ctx.query
获取get请求时?
后面是数据(框架会自动将其转换为JSON对象,使用=
、&
分隔)
- async函数的参数2:next
- async函数返回的是Promise对象
- async中可使用await关键词(
await Promise对象
/await async函数
)执行异步函数- async函数返回的是Promise对象
- async函数的参数1:ctx
next()
执行下一个中间件
next()
:即下一个使用app.use()
注册是中间件- 所有一块一块的函数之间就是通过
next()
联系的,如果没有next()
,则一段代码执行完后就停止,不会继续往下跑了 - 注意:如果是get请求的,则只能往下找同样是处理get请求的中间件,post的则直接跳过。post同理。
await next()
中next()返回下一个中间件,下一个中间件也是返回async函数,async函数返回的是Promise对象。使用它则会等下一个中间件执行完毕再继续往下执行(使用await Promise对象
使用同步写法来写异步)
4.例子:- 例子1:
- 例子2:
- 可以通过路由去执行中间件:
- 所有一块一块的函数之间就是通过