koa2框架基本使用方法

koa2框架

  • koa2框架是原生支持async/await的

async/await的简单示例

  • 回顾以前使用Promise的例子:使用Promise的例子
  • 通过以前的例子来对比使用使用Promise和使用async/await代码1代码2
  • 在async函数中,使用await我们可以获取到Promise对象成功时传递的数据,也可使用 try-catch 截获promise 中reject 的值可使用 try-catch 截获promise 中reject 的值

async/await 要点

更多基础知识可参考笔记ES6 async函数与await关键词

  1. await后面可以追加promise 对象,获取resolve()传递的值
  2. await必须包裹在async 函数里面使用
  3. 执行 async 函数返回的也是一个promise 对象
  4. 可使用 try-catch 截获promise 中reject 的值

安装koa2框架

(所有安装都可加上淘宝镜像 --registry=https://registry.npm.taobao.org来加速)

  1. 安装脚手架工具koa-generatornpm install koa-generator -g
    • 注意:这里是koa,没有2,因为它也可用于1版本的
  2. 初始化koa2项目koa2 项目名
  3. 进入项目目录下,安装package.json中的所有依赖npm install
  4. 由于package.json中缺少全局环境参数,所以手动安装一个:npm i cross-env --save-dev
    • 安装完成后需要修改package.json:修改package.json
  5. **运行项目(热更新)**:npm run dev(package.json中显示已经有nodemon,所以无需重新添加,直接使用即可)
  6. 由package.json的dev可知项目运行先执行的是启动server的文件bin/www,原本端口为3000,现将端口设置为8000bin/www
  7. 重新运行项目后测试测试

项目目录分析

  • 项目目录分析
  • app.js:
    • 各个插件的作用
    • 思考各个插件的实现原理(结合之前学过的知识)
    • 处理get请求和past请求
    • app.js

介绍路由

  • router.get():定义处理get请求的路由
    • 参数1:路由url
    • 参数2:async函数,路由符合时做的事情
  • router.post():定义处理post请求的路由
    • 参数1:路由url
    • 参数2:async函数
  • 注意
    1. router来自中间件’koa-router’
    2. 定义路由后需要在app.js中引入路由并使用**app.use()注册路由**
  • ctx.render()渲染的页面
  • ctx.body返回的内容
  • ctx.params:对象,其中包含路由中传递的参数
    • 比如:例子通过路由获取的参数userName
  • ctx.request.body:对象,其中包含post请求中的数据
  • 用自带的路由举例:
    • 路由对应页面:对应页面
    • 路由和页面

处理GET请求的路由

新建博客路由(router.get())

routes下新建blog.js
blog.js

app.js中注册路由(app.use())

app.js中引入并使用博客路由:
app.js

测试

测试

  • 没用框架的时候,query部分需要我们自己从req的url中的字符串提取query部分后,再使用querystring的parse()将字符串转换为JS对象,现在可以直接得到query对象

处理POST请求的路由

新建用户路由(router.post())

routes下新建user.js
user.js

app.js中注册路由(app.use())

app.js中引入并使用博客路由:
app.js

postman测试

注意是json格式的数据:
postman测试

ctx.request.body

  • **ctx.request.body**中的内容为:postman测试
  • **ctx.request**中的内容为:postman测试
    • 可以看到,我们通过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对象
    • 参数3:(可选)中间件app.use()中可有多个中间件,顺序执行
      • 使用方法:中间的中间件在外部定义 命名async函数,然后在app.use()中调用该函数,最后的中间件使用匿名函数直接书写。
      • 一般最后一个中间件主函数前面的中间件做验证,比如登录验证,如果前面的中间件就发现密码不对则当即停止,不需要继续往下执行

中间件

  • 中间件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对象

next()执行下一个中间件

  • next():即下一个使用app.use()注册是中间件
    • 所有一块一块的函数之间就是通过next()联系的,如果没有next(),则一段代码执行完后就停止,不会继续往下跑了
    • 注意:如果是get请求的,则只能往下找同样是处理get请求的中间件,post的则直接跳过。post同理。
    • await next()中next()返回下一个中间件,下一个中间件也是返回async函数,async函数返回的是Promise对象。使用它则会等下一个中间件执行完毕再继续往下执行(使用await Promise对象使用同步写法来写异步)
      4.例子:
    • 例子1app.js
    • 例子2app.js
    • 可以通过路由去执行中间件routes-blog.js