今天给大家搬运的是利用发布-订阅模式对代码进行解耦

你是否在项目封装的通用代码里这么干过,或者公司目前的代码就是这么做的呢?

举个栗子✏️

公司里的中后台项目封装的通用http库里请求响应拦截器是不是类似大概这样写的?

特别是如果在后端的响应码很多需要分开写逻辑时

js 复制代码
...
import router from '@/router'
import {Modal,message} from 'ant-design-vue'
export class Request {
  instance: AxiosInstance;
  baseConfig: AxiosRequestConfig = {
    baseURL: import.meta.env.VITE_APP_BASE_API,
    timeout: 100000 * 60 * 3 * 100,
  };

  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(Object.assign(this.baseConfig, config));
    this.instance.interceptors.request.use(
      (_config: AxiosRequestConfig) => {
        ...
        return _config;
      },
      (error: AxiosError) => Promise.reject(error)
    );

    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        return response;
      },
      async (error: any) => {
       const data = error?.response?.data
        if (data && data.code === 60009) {
          ...
          Modal.error(...)
        }
        if (data && data.code === 60010) {
        ...
          message.warn(...)
        }
        if (error.response.status === 401) {
          router.push('/login')
        }
        ...
        return Promise.reject(error.response);
      }
    );
  }

这样的话一个网络请求库耦合的东西就太多而显得臃肿。

我们想一个网络请求库它就只需要做网络请求相关的工作就行了,没必要一会儿又需要引入UI组件弹窗显示,一会儿又要引入路由的方法进行跳转

像这样✨

1️⃣ 假如401需要跳转登录页面,触发一个需要路由去处理的事件,然后路由模块自己去接收处理

2️⃣ 假如60009需要UI组件message发出一个警告的提示就触发一个需要UI弹窗组件需要处理的事件,自己去处理

3️⃣ 假如600010需要UI组件Modal发出弹窗确认,触发一个事件,UI组件相应自己去接收处理

......

js 复制代码
  async (error: any) => {
        const data = error?.response?.data
        if (data && data.code === 60009) {
          emit()
        }
        if (data && data.code === 60010) {
          EventEmitter.emit('UI:OPEN_MESSAGE',...)
        }
        if (axios.isCancel(error)) return
        if (error.response.status === 401) {
         EventEmitter.emit('API:UN_AUTH')
        }
        if (data && (data.code ===1||data.code===50002)) {
           EventEmitter.emit('UI:OPEN_MESSAGE',...)
        }
        if (data && data.code !== 60009&&data.code !== 60010) {
             EventEmitter.emit('UI:OPEN_MODAL',...)
        }
        。。。
        return Promise.reject(error.response)
      }

EventEmitter⭐

js 复制代码
const eventNames = ["API:UN_AUTH", "API:INVALID_TOKEN","UI:OPEN_MESSAGE","UI:OPEN_MODAL" ,"..."] as const;
type EventName = (typeof eventNames)[number];

class EventEmitter {
  private listeners: Record<EventName, Set<Function>> = {
    "API:UN_AUTH": new Set(),
    "API:INVALID_TOKEN": new Set(),
  };
  on(eventNames: EventName, listener: Function) {
    this.listeners[eventNames].add(listener);
  }
  emit(eventNames: EventName, ...args: any[]) {
    this.listeners[eventNames].forEach((cb) => cb(...args));
  }
}

export default new EventEmitter();

导出一个全局的EventEmitter,在需要触发和需要订阅的模块引入使用

router

js 复制代码
import eventEmitter from '@utils/EventEmitter'
...
eventEmitter.on('API:UN_AUTH',()=>{
router.push('/login')
})
...

uiUtils

js 复制代码
import eventEmitter from '@utils/EventEmitter'
import {message,Modal} from 'ant-design-vue'
...
eventEmitter.on('UI:OPEN_MESSAGE',(...args)=>{
  message.wran({
  ...
  })
})
eventEmitter.on('UI:OPEN_MODAL',(...args)=>{
  Modal.wran({
  ...
  })
})
...

总结❤️

✅通过这样就能使用发布-订阅模式对业务代码逻辑进行充分解耦拉,也可以在你觉得很臃肿的很多其他业务代码里使用。

✅这样不仅仅又多掌握并运用了一种设计模式在今后吹嘘项目时也可以说自己的项目引入了发布订阅的模式进行代码解耦

相关推荐
程序员猫哥_6 分钟前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html
龙飞056 分钟前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
我爱加班、、12 分钟前
Websocket能携带token过去后端吗
前端·后端·websocket
AAA阿giao12 分钟前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
杨超越luckly18 分钟前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强
hedley(●'◡'●)1 小时前
基于cesium和vue的大疆司空模仿程序
前端·javascript·vue.js·python·typescript·无人机
qq5_8115175151 小时前
web城乡居民基本医疗信息管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
百思可瑞教育1 小时前
构建自己的Vue UI组件库:从设计到发布
前端·javascript·vue.js·ui·百思可瑞教育·北京百思教育
百锦再1 小时前
Vue高阶知识:利用 defineModel 特性开发搜索组件组合
前端·vue.js·学习·flutter·typescript·前端框架
CappuccinoRose1 小时前
JavaScript 学习文档(二)
前端·javascript·学习·数据类型·运算符·箭头函数·变量声明