5月28日 04:25

Koa 和 Express 有什么区别?洋葱模型原理是什么?

Koa 和 Express 最大的区别是中间件模型:Express 是线性顺序执行,Koa 是洋葱模型——请求先进后出,每个中间件可以同时在请求阶段和响应阶段插入逻辑。

具体来说,Express 中间件按注册顺序依次执行,next() 调用后控制权交给下一个中间件,走完就结束了,不会再回来。Koa 通过 async/awaitawait next() 之后的代码在下游中间件执行完后继续运行,天然支持后置处理(比如统一加耗时日志、响应包装)。

其他关键区别:

  • 体量:Express 自带路由、静态文件服务等;Koa 核心只有约 550 行代码,路由等全靠第三方中间件
  • 上下文:Express 分开操作 reqres;Koa 封装成单个 ctx 对象,ctx.request / ctx.response 提供更友好的 API,同时 ctx.req / ctx.res 仍可访问原生对象
  • 错误处理:Express 需要手动在回调里 if (err) 或写错误中间件;Koa 可以在整个中间件链最外层用 try/catch 统一捕获,也可以监听 app.on('error')
  • 异步:Express 基于回调,异步错误容易丢失;Koa 原生 async/await,异步流程可预测

追问

洋葱模型具体怎么执行的?

javascript
app.use(async (ctx, next) => { console.log(1); // 请求进入 await next(); console.log(2); // 响应返回 }); app.use(async (ctx, next) => { console.log(3); await next(); console.log(4); }); // 输出顺序:1 → 3 → 4 → 2

await next() 是分界线,前面是请求阶段逻辑,后面是响应阶段逻辑。这就是"洋葱"——从外层穿到内层,再从内层穿回外层。

为什么 Koa 不内置路由?

设计哲学不同。Koa 团队认为框架核心应该只做 HTTP 请求/响应的流转控制,路由、模板、静态文件这些属于应用层关注点,交给社区按需选择。好处是不用为不需要的功能买单,坏处是新手需要自己拼装中间件栈,上手成本稍高。

Express 中间件能迁移到 Koa 吗?

不能直接迁移。Express 中间件签名是 (req, res, next),Koa 是 async (ctx, next),参数和异步模型完全不同。koa-connect 可以做桥接但不是长久之计,迁移基本等于重写。

实际项目怎么选?

快速出活、生态完善选 Express;需要精细控制请求生命周期、团队习惯 async/await 选 Koa。2026 年的新项目两者都不一定是首选——Fastify 性能更好,NestJS 提供更完整的工程化方案,按团队规模和技术偏好综合判断。

标签:Koa