使用 async/await 写异步中间件需将中间件声明为 async 函数,内部 await 异步操作及 await next() 以确保链式执行与错误冒泡,Express 需 express-async-errors 等方案支持,Koa 原生兼容。

用 async/await 写异步中间件,核心是让中间件函数返回 Promise,并在调用 next() 时正确 await,从而自然串联异步逻辑、统一错误处理、避免回调嵌套。
中间件函数本身要是 async 函数
Express/Koa 等框架的中间件接收 (req, res, next) 参数。若中间件内部有异步操作(如数据库查询、API 调用),直接把中间件声明为 async,就能在内部 await 任何 Promise:
- 不用手动包装成 Promise 或写 .then()
- await 后续语句会等待异步完成再执行,逻辑线性清晰
- 错误可直接用 try/catch 捕获,比传给 next(err) 更直观
await next() 是关键,不是简单调用
在需要“放行”到下一个中间件或路由处理器时,不能只写 next() —— 这样会跳过等待,导致后续逻辑提前执行或竞态问题。必须写 await next():
- 确保当前中间件等下游链全部完成后再继续执行本层的后续代码(比如日志、响应修饰)
- 若下游抛错,await next() 会让错误冒泡到本层 try/catch 中
- 在 Koa 中这是默认行为;Express 中需配合支持 Promise 的封装(如 express-async-errors)或手动处理
统一错误处理:用 try/catch 包裹 await next()
把整个中间件逻辑(含 await next())放在 try/catch 中,就能集中捕获同步和异步错误:
- 数据库查询失败、fetch 报错、JSON 解析异常等,都会被 catch 捕获
- 在 catch 块里调用 next(err)(Express)或 ctx.throw()(Koa),交由全局错误中间件处理
- 避免每个 await 后都写 .catch(),代码更干净
注意 Express 的原生限制与兼容方案
Express 默认不 await 中间件返回的 Promise,所以仅写 async function(req, res, next) { ... } 不足以让 await next() 生效:
- 推荐使用 express-async-errors 包,它自动包装所有 async 中间件,使 await next() 可靠工作
- 或手动封装:next() 返回的 Promise 需显式 await,且最终要调用 res.send() / res.json() 等结束响应,防止挂起
- Koa 天然支持,无需额外适配

















