一、koa2
- 框架:封装原生代码的API,规范流程和格式,提高开发效率(让开发更加关注业务代码)
- 框架与库的区别:
(1)框架是唯一的,库是可以共存
(2)框架关注全流程,库关注单个功能
koa2是nodejs web server框架
(1)官网:https://koa.bootcss.com/
(2)通过async/await语法高效编写web server
(3)中间件机制,合理拆分业务代码
(4)安装:npm install koa --save
koa2体验
const Koa = require('koa')
const app = new Koa()
// contrxt =>ctx 联系上下文
app.use(async (ctx)=>{
ctx.body = 'hellp world'
}).listen(3000) // web server 监听3000端口
- 环境搭建
(1)使用脚手架koa-generator创建koa2项目npm install -g koa-generator
(2)安装完之后,使用命令koa2 --version
或者koa2 -V
检测是否安装成功,安装成功出现版本号,如下:安装与测试图片。
(3)创建koa2项目。执行命令koa2 文件名
,然后cd进入创建好的文件夹。例:
(4)项目运行 创建项目之后,本身有nodemon插件,直接使用
npm run dev
运行即可(5)app.js中导出的app实列在bin下的www中引入
(6)www中监听的3000端口
(7)app.use后面引用的都是"中间件"
- 定义路由,设置问及那名:comment.js
(1)引入koa-router,例:const router = require('koa-router')()
(2)设置前缀
(3)输出:module.exports = router //输出
(4)使用``router.get`,整体可参考如下:
const router = require('koa-router')()
router.prefix('/api')// 前缀
// 定义路由:模拟获取留言板列表
router.get('/list',async (ctx)=>{
ctx.body = "api list"
})
// 创建留言板的路由 ,注意:创建get请求用get,创建post请求用post
router.post('/create',async (ctx)=>{
ctx.body = 'api create'
})
module.exports = router //输出
(5)创建好了路由,在app.js中先引入,然后注册。,例:
(6)注册里面的allowedMethods()是对于404 或者返回是空的情况的一种补充
二、koa2处理http请求
-
如何接收数据和返回数据:
ctx即:res和req的 集合
(1) 获取querysting(url后面的参数)
(2)获取request body
三、koa2中间件
-
什么是中间件:
(1)一个流程上,独立的业务模块
(2)可扩展,可插拔
(3)类似于工厂的流水线
(4)如下,每一个功能模块就是一个中间件
为什么使用使用中间件
(1)拆分业务模块,使代码更加清晰
(2)统一使用中间件,使各业务代码都规范标准
(3)扩展性好,易添加、易删除所有的app.use(...)都是中间件、路由也是中间件(只不过限制了url的规则????);就是说,路由根据url的规则走
模拟登录验证
// 模拟登录(为了使用中间件)app.use所有操作都会经过的
app.use(async (ctx, next) => { // next下一步,该use的下一个中间件,next
const query = ctx.query
if (query.user === 'zhangsan') {
//模拟登录成功
await next() // 执行下一步中间件 。await等待,等待异步执行完,才会执行完下面的代码
} else {
// 模拟登录失败
ctx.body = '请登录'
}
})
四、洋葱圈模型
- 每个中间件都是async函数(函数运行机制,没讲过。)
-
每一层洋葱圈都是一个中间件(先进入哪一个中间件,最后从那个中间件出)
- 回顾async/await
(1)await调用的时候,需要等当前执行完之后,才可以往下执行。类似开发的时候,等待一个结果,必须拿到结果之后,才可以继续使用执行。
(2)fetch 原生api,一种HTTP数据请求的方式,是XMLHttpRequest的一种替代方案。类似与ajax,发送请求用的。所以外层调用的时候需要等待一个结果。
(3)代码演示,不完整,只是一个执行顺序。
// 演示async await 的执行顺序
// 代码放在浏览器中运行。
// 加载一张图片。使用async声明函数。
async function getImg(url = '') {
await fetch(url)
// fetch 原生api,一种HTTP数据请求的方式,是XMLHttpRequest的一种替代方案。类似与ajax,发送请求用的
}
async function fn(){
const url = 'https://upload-images.jianshu.io/upload_images/19813229-97dc09156676ab94.png'
const start = Date.now() // 记录当前时间
await getImg(url) //调用getImg,加载图片
// await调用的时候,进入getImg函数,等getImg函数执行完之后(这行代码才算执行完),才会执行下面的代码
const ms = Date.now() - start // 计算时间差。
console.log(`加载图片时间:${ms}`)
}
fn()
- 演示koa2中间件的洋葱圈模型,代码示例:
// 演示koa2中间件的洋葱圈模型
const Koa = require('koa')
const app = new Koa()
// logger
app.use(async (ctx, next) => {
await next() // 执行下一个中间件(对于当前来说是x-response-time)
const rt = ctx.response.get('X-Response-Time') //res 。get获取时间差
console.log(`${ctx.method} ${ctx.url} - ${rt}`)
})
// x-response-time
app.use(async (ctx, next) => {
const start = Date.now()
await next()
const ms = Date.now() - start
ctx.set('X-Response-Time',`${ms}ms`) // X-Response-Time与上一个中间件res这里的要一致
// set 记录/设置 时间差
})
// response
app.use(async (ctx, next) => {
ctx.body = 'Hello 洋葱圈'
})
app.listen(3000)
console.log('监听3000端口')