一、Koa 中间件的原理
koa 把很多 async 函数组成一个处理链,每个 async 函数都可以做一些自己的事情,然后用 await next()
来调用下一个 async 函数。我们把每个 async 函数称为 middleware,这些 middleware 可以组合起来,完成很多有用的功能。koa 的中间件是通过 Async/Await 实现的,中间件执行顺序是“洋葱圈”模型,如图:
原理:中间件之间通过 next 函数联系,当一个中间件调用 next()
后,会将控制权交给下一个中间件,直到下一个中间件不再执行 next()
时沿路返回,依次将控制权交给上一个中间件。
二、自定义 Koa 中间件
这里以三个中间件 m1.js、m2.js、m3.js 为例
代码语言:javascript复制$ cd project
$ mkdir middleware
$ cd middleware
$ touch m1.js
$ touch m2.js
$ touch m3.js
m1.js:
代码语言:javascript复制function m1 (ctx) {
global.console.log('m1')
}
module.exports = function () {
return async function (ctx, next) {
global.console.log('m1 start')
m1(ctx)
await next()
global.console.log('m1 end')
}
}
m2.js:
代码语言:javascript复制function m2 (ctx) {
global.console.log('m2')
}
module.exports = function () {
return async function (ctx, next) {
global.console.log('m2 start')
m2(ctx)
await next()
global.console.log('m2 end')
}
}
m3.js:
代码语言:javascript复制function m3 (ctx) {
global.console.log('m3')
}
module.exports = function () {
return async function (ctx, next) {
global.console.log('m3 start')
m3(ctx)
await next()
global.console.log('m3 end')
}
}
其中,参数 ctx 是由 koa 传入的封装了 request 和 response 的变量,我们可以通过它访问 request 和 response,next 是 koa 传入的将要处理的下一个异步函数。
app.js:
代码语言:javascript复制const Koa = require('koa')
const app = new Koa()
const m1 = require('./middleware/m1')
const m2 = require('./middleware/m2')
const m3 = require('./middleware/m3')
app.use(m1())
app.use(m2())
app.use(m3())
输出:
三、Koa 中间件的应用
可用于登陆验证的中间件:
loginCheck.js:
代码语言:javascript复制module.exports = async (ctx, next) => {
if (ctx.session.username) {
// 登陆成功则执行 await next() 进行下一步操作
await next()
return
}
// 登陆失败则禁止继续执行,所以不需要执行 next()
ctx.body = {
code: -1,
msg: '登陆失败'
}
}
在删除操作中使用 loginCheck.js :
代码语言:javascript复制router.post('/delete', loginCheck, async (ctx, next) => {
const author = ctx.session.username
const id = ctx.query.id
// handleDelete() 是一个处理删除的方法,返回一个 promise
const result = await handleDelete(id, author)
if (result) {
ctx.body = {
code: 0,
msg: '删除成功'
}
} else {
ctx.body = {
code: -1,
msg: '删除失败'
}
}
})
更多 Koa ctx:https://koa.bootcss.com/#context