Egg - 中间件易错点和洋葱模型

文章讨论了在Egg.js中编写中间件时常见的错误,特别是关于洋葱模型的执行顺序。中间件的执行基于洋葱模型,请求从外到内穿过每个中间件,然后从内到外返回响应。如果在中间件中不调用`awaitnext()`,必须使用`return`结束,否则会导致请求阻塞。作者通过示例代码强调了在处理权限检查时,返回错误状态后需使用`return`来确保请求能继续进行的重要性。
摘要由CSDN通过智能技术生成

Egg - 中间件易错点和洋葱模型

一. 易错中间件编码

废话不多说,我给大家写个Demo

const auth = () => {
  return async (ctx: Context, next: () => any) => {
	const user = getUser();
    if (user) {
      const {hasPermission} = user;
      // 如果没有权限
      if (!hasPermission) {
        ctx.body = {
          CODE: 'NO_PERMISSION',
        };
      } else{
         await next();
	  }
    }
  };
};

export default auth;

伪代码很简单,意思就是:

  • 如果用户没有权限,返回一个固定的Code
  • 如果有权限则放行。

这段代码从语义上看其实并没有任何问题,用过Egg的小伙伴也知道,ctx.body对象赋值,也相当于给最终返回对象赋值。

但是这个代码却有着很严重的问题,我们先来回顾一下洋葱模型。

1.1 中间件和洋葱模型

解释如下:

  1. Egg.js 中间件的执行顺序是按照洋葱模型来进行的,即请求从外到内依次经过每个中间件,再从内到外依次返回响应结果。
  2. 在这个过程中,每个中间件都需要执行 await next() 将控制权交给下一个中间件或路由处理函数。
  3. 如果某个中间件没有执行 await next(),则会导致请求无法继续往下执行,也就无法返回响应结果。
  4. 因此,如果不执行 await next(),则需要使用 return 明确地结束当前中间件函数的执行,并将控制权交还给上一个中间件或路由处理函数,以保证请求能够正常地继续执行。

我们重点关注最后一句话,就是说,如果你不执行await next(),一定要执行“return” 函数。即使你给ctx.body赋值了也没有用,因为程序它会阻塞。

那么正确的做法就是:

const auth = () => {
  return async (ctx: Context, next: () => any) => {
	const user = getUser();
    if (user) {
      const {hasPermission} = user;
      // 如果没有权限
      if (!hasPermission) {
        ctx.body = {
          CODE: 'NO_PERMISSION',
        };
        return;
      } 
    }
    await next();
  };
};

export default auth;

写中间件的时候,一定要注意这个点:

  1. 你的中间件必须有两种返回:要么return,要么await next()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zong_0915

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值