Koa 洋葱模型与 async 中间件
Koa 洋葱模型与 async 中间件
Koa 是 Express 原班团队打造的下一代框架,体积更小、没有内置任何中间件,核心机制就是著名的洋葱模型。
什么是洋葱模型
中间件的执行像穿过洋葱:请求从外层进入,逐层向内;next() 之后的代码在响应回程中从内向外执行:
app.use(async (ctx, next) => {
console.log('1 进入')
await next() // 交给内层,内层全部完成后才继续
console.log('1 出去')
})
app.use(async (ctx, next) => {
console.log('2 进入')
await next()
console.log('2 出去')
})
// 输出:1 进入 → 2 进入 → 2 出去 → 1 出去
Express 也有 next,但因为回调时代没有强制 await,"回程逻辑"写起来很别扭。Koa 的中间件全是 async 函数,await next() 让"前后环绕"成为天然结构——日志计时、异常捕获、事务包裹都极其优雅:
// 统一错误处理:一个外层中间件兜住所有内层异常
app.use(async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.status = err.statusCode || 500
ctx.body = { message: err.message }
}
})
// 耗时统计
app.use(async (ctx, next) => {
const start = Date.now()
await next()
ctx.set('X-Response-Time', Date.now() - start + 'ms')
})
ctx 上下文
Express 是 req/res 两个对象,Koa 合并为一个 ctx,并封装了常用属性:ctx.request/ctx.response、ctx.query、ctx.params、ctx.body(直接赋对象,自动 JSON 序列化)、ctx.status。
手写核心 compose
洋葱模型的实现核心是把中间件数组组合成一条嵌套调用链:
function compose(middleware) {
return function (ctx) {
function dispatch(i) {
const fn = middleware[i]
if (!fn) return Promise.resolve()
return Promise.resolve(fn(ctx, () => dispatch(i + 1)))
}
return dispatch(0)
}
}
关键:next 就是 () => dispatch(i+1),async 函数 await 它时,后面所有中间件都被 await,回程顺序自然形成。
Express 还是 Koa
- 生态丰富、上手快、传统 MVC → Express
- async 体验、干净的中间件模型、需要自己掌控架构 → Koa(Egg.js 等上层框架也基于它)
理解了 compose,这一类中间件框架(甚至 h3/Nitro)在你眼里就都透明了。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~