手把手写一个迷你版的koa2

koa2中间件的简单实现

说明

  1. 本次的简单实现重点在中间件的原理上(compose函数),而其他部分的实现就忽略了很多细节,只是让代码能跑起来。

  2. express不同,koa2的路由处理与它本身是分开的(路由处理用koa-router)。这里的内容不包括路由处理。

  3. 本次的实现内容包括koa的uselisten和中间件的洋葱圈模型。

koa中间件执行机制

koa2中间件使用的是洋葱圈模型。这里附上一张网络上广为流传的图:

洋葱圈模型

从这张图也能知道个大概意思:请求从最外层传到最里层,响应从最里层逐层往外传递。

下面来看一个经典的例子理解一下(如果之间不了解koa中间件机制的话,请跟着注释一步步地走):

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

// logger
app.use(async (ctx, next) => {
   
  // 1. request: 请求处理开始!执行这一行代码,然后往下走
  console.log('第一层洋葱 - 开始')
  // 2. request: 遇到一个异步函数,进入这个中间件
  await next();

  // 12. response: 第二个中间件执行结束后返回这里,代码往下执行,获得之前在ctx中存储的变量
  const rt = ctx.response.get('X-Response-Time');
  // 13. response: 控制台打印 请求方法 请求路径 响应时间
  console.log(`${
     ctx.method} ${
     ctx.url} - ${
     rt}`);
  // 14. response: 所有中间件执行结束!
  console.log('第一层洋葱 - 结束')
});

// x-response-time
app.use(async (ctx, next) => {
   
  // 3. request: 从第一个中间件进入了这里,执行这一行代码,然后往下走 
  console.log('第二层洋葱 - 开始')
  // 4. request: 继续执行代码,存储当前时间戳
  const start = Date.now();
  // 5. request: 又遇到一个异步函数,进入这第三个中间件
  await next();

  // 9. response: 第三个中间件执行结束后返回这里,代码往下执行,获得 ms 变量:第三个中间件的执行时间
  const ms = Date.now() - start;
  // 10. response: 设置 ctx属性,值可以从ctx.response中拿到
  ctx.set('X-Response-Time', `${
     ms}ms`);
  // 11. response: 第二个中间件执行结束,返回到第一个中间件的next()下方
  console.log('第二层洋葱 - 结束')
});

// response
app.use(async ctx => {
   
  // 6. request: 从第二个中间件进入到了这里,执行这一行代码,然后往下走
  console.log('第三层洋葱 - 开始')
  // 7. 收到响应数据,将 Hello World 返回给前端
  ctx.body = 'Hello World';
  // 8. response: 第三个中间件执行结束,响应阶段开始,返回到第二个中间件的 next() 下方
  console.log('第三层洋葱 - 结束')
});

// 该函数优先于上面所有函数的执行!
app.listen(8000, () =>
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值