Koa 洋葱模型
Koa 中间件的执行机制和洋葱模型原理
问题
什么是 Koa 的洋葱模型?它是如何工作的?
解答
Koa 的洋葱模型是一种基于中间件的请求处理机制。请求像穿过洋葱一样,从外层中间件进入,到达核心后再从内向外返回。
执行流程
洋葱模型的执行分为两个阶段:
1. 请求阶段(外 → 内)
从第一个中间件开始,遇到 await next() 时进入下一个中间件,直到最后一个中间件执行完毕。
2. 响应阶段(内 → 外)
从最后一个中间件返回,依次执行每个中间件 await next() 之后的代码,最终返回响应。
代码示例
const Koa = require('koa');
const app = new Koa();
// 中间件 1
app.use(async (ctx, next) => {
console.log('1 - 请求开始');
await next();
console.log('1 - 响应结束');
});
// 中间件 2
app.use(async (ctx, next) => {
console.log('2 - 处理请求');
await next();
console.log('2 - 处理响应');
});
// 中间件 3
app.use(async (ctx, next) => {
console.log('3 - 业务逻辑');
ctx.body = 'Hello Koa';
});
app.listen(3000);
// 输出顺序:
// 1 - 请求开始
// 2 - 处理请求
// 3 - 业务逻辑
// 2 - 处理响应
// 1 - 响应结束
简化实现
function compose(middlewares) {
return function (ctx) {
function dispatch(i) {
const middleware = middlewares[i];
if (!middleware) return Promise.resolve();
return Promise.resolve(
middleware(ctx, () => dispatch(i + 1))
);
}
return dispatch(0);
};
}
关键点
- 中间件通过
await next()控制执行流程,之前的代码在请求阶段执行,之后的代码在响应阶段执行 - 执行顺序是”先进后出”,类似栈结构,形成洋葱状的层层包裹
- 每个中间件可以修改
ctx对象,影响后续中间件和最终响应 - 错误处理中间件应放在最外层,可以捕获内层中间件的异常
- 必须调用
await next()才能将控制权传递给下一个中间件,否则会中断执行链
目录