20行代码实现【洋葱模型】,其实没那么难理解~

每日知识分享~

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心~

洋葱模型

洋葱模型是什么呢?作用是什么呢?

先说说他的作用吧,他的作用是为了对一个请求的整个生命周期做一个统一的管理,一个请求的生命周期包括请求、响应。由于实现方式像一层一层剥开洋葱,所以叫洋葱模型~

举例子

可能很多人会觉得一脸懵逼?不知道我在表述什么?那我通过两个例子来说明,大家可能就比较清晰了~

Axios 拦截器

相信很多人在项目中都用过 Axios 的拦截器

  • 请求拦截器
  • 响应拦截器
axiosInstance
.interceptors
.request.use((config) => {
  console.log(config) // {}
  config.name = 'sunshine_lin'
}

axiosInstance
.interceptors
.response.use((res) => {
  console.log(res.config)
  // { name: 'sunshine_lin' }
}

在每次请求中,请求拦截器和响应拦截器中,获取到的config是相通的,也就是同一个对象。

我们甚至可以多个拦截器

// 请求拦截器1
axiosInstance
.interceptors
.request.use((config) => {
  console.log(config) // {}
  config.name = 'sunshine_lin'
  
  return config
}

// 请求拦截器2
axiosInstance
.interceptors
.request.use((config) => {
  console.log(config)
  // { name: 'sunshine_lin' }
  config.age = 20
  
  return config
}

// 响应拦截器1
axiosInstance
.interceptors
.response.use((res) => {
  console.log(res.config)
  // { name: 'sunshine_lin',
  //   age: 20
  // }
  res.data = 1
  
  return res
}

// 响应拦截器2
axiosInstance
.interceptors
.response.use((res) => {
  console.log(res.data) // 1
  
  return res
}

其实基础比较好的同学,可以想象出他的实现原理基本(伪代码)就是:

// 伪代码

// 收集
const tasks = []
const use = (fn) => {
  tasks.push(fn)
}

// 执行
const config = {}
tasks.forEach(fn => {
  config = fn(config)
})

Koa

Koa 是一个 Nodejs 的框架,他也有洋葱模型的实践,比如:

const koa = new Koa()

koa.use(async (ctx, next) => {
  console.log(1)
  console.log(ctx) // {}
  await next()
  console.log(ctx) 
  // { name: 'sunshine_lin', age: '20' }
  console.log(2)
})

koa.use(async (ctx, next) => {
  console.log(3)
  ctx.name = 'sunshine_lin'
  await next()
  console.log(4)
})

koa.use(async (ctx, next) => {
  console.log(5)
  ctx.age = '20'
})

koa.listen(3000)

执行的结果为:

就感觉是,遇到 next 就一层一层往两边掰开。

简单实现洋葱模型

function action(instance, ctx{
  // 记录索引
  let index = 1

  function next({
    // 记录执行的中间件函数
    const nextMiddleware = instance.middlewares[index]
    if (nextMiddleware) {
      index++
      nextMiddleware(ctx, next)
    }
  }
  // 从第一个开始执行
  instance.middlewares[0](ctx, next)
}


class Koa {
  middlewares = []
  use(fn) {
    this.middlewares.push(fn)
  }
  listen(port) {
    Promise.resolve({}).then((ctx) => {
      action(this, ctx)
    })
  }
}

结语

我是林三心

  • 一个待过小型toG型外包公司、大型外包公司、小公司、潜力型创业公司、大公司的作死型前端选手;
  • 一个偏前端的全干工程师;
  • 一个不正经的掘金作者;
  • 逗比的B站up主;
  • 不帅的小红书博主;
  • 喜欢打铁的篮球菜鸟;
  • 喜欢历史的乏味少年;
  • 喜欢rap的五音不全弱鸡

如果你想一起学习前端,一起摸鱼,一起研究简历优化,一起研究面试进步,一起交流历史音乐篮球rap,可以来俺的摸鱼学习群哈哈,点这个,有7000多名前端小伙伴在等着一起学习哦 --> 

相关推荐

  • 看了粉丝的简历,总结一篇面试避坑指南
  • 学会这几个常用功能,给你的 vue3 项目加点餐!
  • 参营有奖|30分钟快速上手ES Serverless!鹅厂大牛带你玩转日志分析
  • 腾讯广告商品中台流程编排引擎架构实现
  • 聊聊前蚂蚁CTO鲁肃
  • 组织惯性,百度副总裁离职只是冰山一角
  • Spring Boot整合ElasticSearch实战 - 第511篇
  • 从明天起,做一个 Rust 程序员
  • springboot第71集:字节跳动全栈一面经,一文让你走出微服务迷雾架构周刊
  • MQ消息积压,把我整吐血了
  • 3 个好玩的前端开源项目「GitHub 热点速览」
  • Spring Security 如何防止 XSS 攻击
  • 面试官:数据库 delete 表数据,磁盘空间还是被一直占用,为什么?
  • 面试官:宕机了,Redis 如何避免数据丢失?
  • 领导如何看待不争不抢的员工?
  • 有些老年痴呆​30到40岁就有苗头了......
  • Altman首提GPT-7设想:每个人都可以访问其计算资源!
  • OpenAI模型终于更新!强大视听能力的GPT-4o将面向所有用户,其前身正是神秘的gpt2!
  • 思维链不存在了?纽约大学最新研究:推理步骤可「省略」
  • MIT等惊人发现:全世界AI已学会欺骗人类!背刺人类盟友,佯攻击败99.8%玩家