洋葱模型学习笔记

342 阅读1分钟

什么是洋葱模型

简单来说,就是再不改变原有方法的情况下,在该方法的外侧增加钩子函数,以达到提前拦截与增强输出的效果。

一般中间件都是以洋葱模型的构建方式实现的,例如常用的 node 中的 koa 框架、请求插件 axios 中的 requestresponse 拦截器等。

为什么使用洋葱模型

axios.post 发送post请求为例:

  1. 首先进入 axios.interceptors.request 的拦截器中,添加 headers 参数,处理请求数据。

  2. 执行 axios.post 方法

  3. 请求成功后获取响应,并在 axios.interceptors.response 拦截器中处理响应数据

  4. 将处理好的数据,通过 Promise 的方式发送到订阅数据的地方。

我们一般处理请求时就是按照上面这个思路来。从上面的例子我们可以看出,我们可以不修改原函数的情况下,轻松处理异步调用顺序、增强原函数的输入输出。

用尾递归实现一个洋葱模型

const m1 = (ctx, next) => {
  ctx.req.user = null;
  console.log('中间件1 进入', ctx.req);

  next()

  console.log('中间件1 退出', ctx.req);
}

const m2 = (ctx, next) => {
  ctx.req.user = { id: 1 };
  console.log('中间件2 进入');

  next()

  console.log('中间件2 退出');
}

const m3 = () => {
  console.log('中间件3');
}

const middlewares = [m1, m2, m3];
const context = { req: {}, res: {} };
let index = 0

function next(i) {
    if (index >= middlewares.length) return

    let middleware;
    while(index < middlewares.length) {
        middleware = middlewares[index++]
        middleware(context, next)
    }
}

next();