浅谈Koa洋葱模型

我们已经知道 koa2 中间件是基于async/await 实现的,其执行过程是通过next来驱动的,于是,koa2 就有了一个特殊的执行顺序,我们为这种执行顺序设定了一个模型叫–洋葱模型。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I8R2luoz-1618999868300)(在这里插入图片描述]
)
现在假想,你手里有一支牙签,横向穿过一个洋葱,是不是会层层穿透?从第一层进去、到第二层、第三次…然后到中间层后,再层层穿透的出,从第三层出、第二层、第一层…。其实我们的koa2中间件执行顺序也是这样的。抛开业务代码,用koa2官网的一个例子做实验

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

// logger
app.use(async (ctx, next) => {
  console.log('第一层洋葱 - 开始')
  await next();
  const rt = ctx.response.get('X-Response-Time');
  console.log(`${ctx.method} ${ctx.url} - ${rt}`);
  console.log('第一层洋葱 - 结束')
});

// x-response-time
app.use(async (ctx, next) => {
  console.log('第二层洋葱 - 开始')
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
  console.log('第二层洋葱 - 结束')
});

// response
app.use(async ctx => {
  console.log('第三层洋葱 - 开始')
  ctx.body = 'Hello World';
  console.log('第三层洋葱 - 结束')
});

app.listen(8000);

我们执行一下上面代码。会发现打印结果是

第一层洋葱 - 开始
第二层洋葱 - 开始
第三层洋葱 - 开始
第三层洋葱 - 结束
第二层洋葱 - 结束
第一层洋葱 - 结束

看另外一个例子

const one = (ctx, next) => {
  console.log('>> one');
  next();
  console.log('<< one');
}

const two = (ctx, next) => {
  console.log('>> two');
  next();
  console.log('<< two');
}

const three = (ctx, next) => {
  console.log('>> three');
  next();
  console.log('<< three');
}

app.use(one);
app.use(two);
app.use(three);
>> one
>> two
>> three
<< three
<< two
<< one
one = (ctx, next) => {
  console.log('>> one');
   next();----------------> two = (ctx, next) => {
                              console.log('>> two');
                              next();------------------> three = (ctx, next) => {
                                                           console.log('>> three');
                                                           next();--------------------|
                                                           console.log('<< three');<--| 
                                                         }
                              console.log('<< two');
                            }

  console.log('<< one'); 
}      

three内有没有调用next()都不影响冒泡,没有调用next(),就是不会再传递给下一个中间件,此时three可以看作是一个普通的方法

one = (ctx, next) => {
  console.log('>> one');
   next();----------------> two = (ctx, next) => {
                              console.log('>> two');
                              next();------------------> three = (ctx, next) => {
                                                           console.log('>> three');
                                                           console.log('<< three');
                                                         }
                              console.log('<< two');
                            }

  console.log('<< one'); 
}      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值