Koa 中间件不调用 await next() 的影响

分析 Koa 中间件未调用 await next() 时的执行流程和影响

问题

在 Koa 中,如果一个中间件没有调用 await next(),后续的中间件还会执行吗?

解答

不会执行。当中间件没有调用 await next() 时,控制权不会传递给下一个中间件,请求处理流程会在当前中间件终止。

Koa 的中间件采用洋葱模型,通过 await next() 将控制权传递给下游中间件。如果省略这个调用,后续中间件将被跳过,请求会直接返回响应。

这个特性常用于权限验证、请求拦截等场景。例如,权限检查中间件可以根据验证结果决定是否继续处理:

app.use(async (ctx, next) => {
  if (await checkUserPermission(ctx)) {
    // 权限验证通过,继续执行后续中间件
    await next();
  } else {
    // 权限不足,直接返回 403,不执行后续中间件
    ctx.status = 403;
    ctx.body = { error: 'Permission denied' };
  }
});

完整示例:

const Koa = require('koa');
const app = new Koa();

// 中间件 1
app.use(async (ctx, next) => {
  console.log('中间件 1 - 开始');
  await next();
  console.log('中间件 1 - 结束');
});

// 中间件 2 - 不调用 next()
app.use(async (ctx, next) => {
  console.log('中间件 2 - 执行');
  ctx.body = 'Response from middleware 2';
  // 没有调用 await next()
});

// 中间件 3 - 不会执行
app.use(async (ctx, next) => {
  console.log('中间件 3 - 这里不会执行');
});

// 输出结果:
// 中间件 1 - 开始
// 中间件 2 - 执行
// 中间件 1 - 结束

关键点

  • 不调用 await next() 会中断中间件链,后续中间件不会执行
  • 这是 Koa 洋葱模型的核心机制,控制权需要显式传递
  • 常用于权限验证、请求拦截等需要提前终止请求的场景
  • 确保在需要继续处理的分支中调用 await next(),避免意外中断请求流程