axios封装时对config参数的一点思考

news2025/1/13 7:36:00


目 录

  • 0、起因
  • 1、冷静分析
  • 2、一个简单粗糙但是能用的封装


0、起因

创建一个实例:

const service = axios.create({
  baseURL: "/api",
  timeout: 3e3,
  withCredentials: true,
  headers:{
    "Content-Type": "application/json"
  }
})

简单封装:

export default{
  Post(url:string, params = {} ) {
      return new Promise((resolve, reject) => {
          service.post(url, params ).then(res => {
              resolve(res.data);
          }).catch(err => {
              reject(err)
          })
      })
  },
}

封装时放开 config 配置:

export default{
  Post(url:string, params = {}, config: AxiosRequestConfig<any> = {}) {
      return new Promise((resolve, reject) => {
          service.post(url, params, config).then(res => {
              resolve(res.data);
          }).catch(err => {
              reject(err)
          })
      })
  },
}

源码里定义的几个接口:
主要信息:可以传一个 config 对象

  request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
  get<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
  delete<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
  head<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
  options<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: AxiosRequestConfig<D>): Promise<R>;
  post<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;
  put<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>): Promise<R>;

  像往常一样机械封装 axios实例,封装 get、post、put、delete方法,之前都是秉持着“能用就行”的原则,力图简单快速,直接砍掉了方法自带的config参数,仅留下了 url、data 两个,其他配置参数(baseURL、headers…)开始就统一默认配置好。
  但是随着不同需求的出现,问题也暴露了:请求不够灵活,没法单独定制 header 等信息。于是考虑封装时开放 config 参数,但是并不是每次都需要定制,大部分情况下默认就行。于是乎就纠结默认值的问题,之前没传的时候,底层获取到的是 undefined,那么默认值 undefined 肯定没问题。问题在于,如果传入了 config ,那他是会替换掉实例的配置,还是合并?

1、冷静分析

  一想肯定是合并,但是由于之前封装的时候失误,没有用实例而是直接用 axios 封装,导致出现 “初始配置丢失” 的假象,就打开源码一探究性(主要是我也很好奇他的很多东西,正好这个机会去䁖一䁖🤣)。
  顺着源码,一路找到了 Axios 身上的 request ,然后还是自代码里找到了答案,实例自身会将初始配置对象存一份在 defaults 上,request 接到 config 后,会有一步合并的操作,也就是 mergeCofig。源码的后边,也是用合并后的 config 发起请求,返回对应的 promise 对象。

axios/lib/core/Axios.js

class Axios {
  constructor(instanceConfig) {
  	// ** 看这里
    this.defaults = instanceConfig;
    this.interceptors = {
      request: new InterceptorManager(),
      response: new InterceptorManager()
    };
  }
  request(configOrUrl, config) {
    if (typeof configOrUrl === 'string') {
      config = config || {};
      config.url = configOrUrl;
    } else {
      config = configOrUrl || {};
    }
	// ** 看这里
    config = mergeConfig(this.defaults, config);
    // 省略好几个字。。。
    }
    
  // 省略好多源码....

   // ** 看这里
   let newConfig = config;

    i = 0;

    while (i < len) {
      const onFulfilled = requestInterceptorChain[i++];
      const onRejected = requestInterceptorChain[i++];
      try {
        newConfig = onFulfilled(newConfig);
      } catch (error) {
        onRejected.call(this, error);
        break;
      }
    }

    try {
      // ** 看这里
      promise = dispatchRequest.call(this, newConfig);
    } catch (error) {
      return Promise.reject(error);
    }
    // 省略好多源码....
}

2、一个简单粗糙但是能用的封装

请求、响应拦截器可以更精致一点🤣

import axios, { AxiosRequestConfig } from "axios"

const service = axios.create({
  baseURL: "/api",
  timeout: 3e3,
  withCredentials: true,
  headers:{
    "Content-Type": "application/json"
  }
})

service.interceptors.request.use(config =>{
  config.headers["token"] = "dont forget to carry the token"
  return config
}, error=>{
  
})

service.interceptors.response.use((res)=>{
  // 错误处理 token过期等
  return res.data
}, error=>{

})

export {service}

export default {
  Get(url: string, config: AxiosRequestConfig<any> = {}) {
    return new Promise((resolve, reject) => {
      service.get(url, config).then(res => {
          resolve(res.data)
      }).catch(err => {
          reject(err)
      })
    })
  },
  Post(url:string, params = {}, config: AxiosRequestConfig<any> = {}) {
      return new Promise((resolve, reject) => {
          service.post(url, params, config).then(res => {
              resolve(res.data);
          }).catch(err => {
              reject(err)
          })
      })
  },
  Put(url:string, params = {}, config: AxiosRequestConfig<any> = {}) {
    return new Promise((resolve, reject) => {
        service.put(url, params, config).then(res => {
            resolve(res.data);
        }).catch(err => {
            reject(err)
        })
    })
  },
  Delete(url:string, config: AxiosRequestConfig<any> = {}) {
    return new Promise((resolve, reject) => {
        service.delete(url, config).then(res => {
            resolve(res.data);
        }).catch(err => {
            reject(err)
        })
    })
  },

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/601779.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32控制OLED介绍

OLED&#xff0c;即有机发光二极管&#xff08;Organic Light-Emitting Diode&#xff09;&#xff0c;又称为有机电激光显示&#xff08;Organic Electroluminesence Display&#xff0c; OELD&#xff09;。 OLED 由于同时具备自发光&#xff0c;不需背光源、对比度高、 厚度…

人工智能(pytorch)搭建模型7-利用pytorch搭建一个BiLSTM+CRF模型,实现简单的命名实体识别

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型7-利用pytorch搭建一个BiLSTMCRF模型&#xff0c;实现简单的命名实体识别&#xff0c;BiLSTMCRF 模型是一种常用的序列标注算法&#xff0c;可用于词性标注、分词、命名实体识别等任务。本…

软件安全概述

软件定义是&#xff1a;计算机程序、规则和可能相关的文档。 软件是程序、数据和文档的集合体。 零日漏洞、零日攻击 零日漏洞是指未被公开披露的软件漏洞&#xff0c;没有给软件的作者或厂商以时间去为漏洞打补丁或是给出建议解决方案&#xff0c;从而攻击者能够利用这种漏洞破…

ROS:话题消息(Message)的定义与使用

目录 一、话题模型二、自定义话题消息2.1定义msg文件2.2在package.xml中添加功能包依赖2.3在CMakeLists.txt中添加编译选项2.4编译生成C头文件或Python库 三、创建代码并编译运行&#xff08;C&#xff09;3.1创建代码3.2编译 四、运行 一、话题模型 自定义一个消息类型“Pers…

python接口测试之测试报告

在本文章中&#xff0c;主要使用jenkins和编写的自动化测试代码&#xff0c;来生成漂亮的测试报告&#xff0c;关于什么是CI这些我就不详细的介绍了&#xff0c;这里我们主要是实战为主。 首先搭建java的环境&#xff0c;这个这里不做介绍。搭建好java的环境后&#xff0c;在h…

Python:Python编程:从入门到实践__超清版:Python标准库:线程

Python线程与安全 实现线程安全有多重方式&#xff0c;常见的包括&#xff1a;锁&#xff0c;条件变量&#xff0c;原子操作&#xff0c;线程本地存储等。 &#x1f49a; 1. 锁2. 条件变量3. 通过 join 阻塞当前线程4. 采用 sleep 来休眠一段时间5. 原子操作5.1 使用 threading…

【I2C】Linux I2C子系统分析

文章目录 一、I2C体系架构二、主要的结构体1. i2c_adapter2. i2c_algorithm3. i2c_driver4. i2c_client4.1 方式一&#xff1a;通过I2C bus number静态方式来创建4.2 方式二&#xff1a;通过Device Tree来创建4.3 方式三&#xff1a;直接通过i2c_new_device来创建4.3 方式四&am…

openEuler22.03制作openstack平台使用的镜像

系列文章目录 第一章 openEuler22.03制作openstack平台使用的镜像 文章目录 系列文章目录前言一、virt-manager上的准备工作1、网卡类型切换为virtio2、IDE驱动设置成Virtio3、Display设置成vnc3、虚拟机系统分区 二、安装普通工具包三、安装云化工具包1、安装工具包2、修改配…

数字化转型,企业为什么要转型?如何转型?

数字化转型是利用数字化技术&#xff08;例如云计算、大数据、人工智能、物联网、区块链等&#xff09;和能力来驱动组织商业模式创新和商业生态系统重构的途径和方法即是数字化转型。其目的是实现企业业务的转型、创新、增长。 核心强调了两点&#xff0c;其一是数字化技术的应…

每日一练 | 华为认证真题练习Day51

1、如下图所示&#xff0c;IPSec传输模式中AH的头部应该插入到以下哪个位置&#xff1f; A. 1 B. 2 C. 3 D. 4 2、以下哪种远程登录方式最安全&#xff1f; A. Telnet B. Stelnet v100 C. Stelnet v2 D. Stelnet v1 3、以下业务模块的ACL默认动作为permit的是&#xff1…

玩转 ChatGPT,看这条就够了,Prompt 最全中文合集

Prompt 最全中文合集 玩转 ChatGPT&#xff0c;看这条就够了&#xff01; &#x1f680; 简化流程&#xff1a;ChatGPT Shortcut 提供了快捷指令表&#xff0c;可以快速筛选和搜索适用于不同场景的提示词&#xff0c;帮助用户简化使用流程。 &#x1f4bb; 提高生产力&#…

CSDN打出各种数学符号和数学公式

目录 1、基本四则运算2、指数对数3、根号、省略号、向量4、大&#xff08;小&#xff09;于等于号5、特殊符号、希腊字母符号6、累加累乘7、矩阵8、更改公式中的颜色 我们在用CSDN打出各种数学符号和数学公式时&#xff0c;需要学习一些关于LaTex的语法&#xff0c;在此做一个记…

java数组学习

一、数组的概述 1.数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合&#xff0c; 并使用一个名字命名&#xff0c;并通过编号的方式对这些数据进行统一管理。 2.数组相关的概念: >数组名 >元素 >角标、下标、索引 >数组的长度&#xff1a;元素…

联通云数据库CUDB:基于openGauss打造新一代自主创新云原生数据库

总体概述 联通云彰显央企担当&#xff0c;围绕国家对信息技术基础软件的政策要求&#xff0c;开展数据库自主研发。在openGauss开源社区版软件基础上&#xff0c;聚焦政企市场&#xff0c;坚持内核创新&#xff0c;完善工具生态&#xff0c;基于海量云存储能力、存算分离架构…

React中的懒加载以及在Ice中实践

您好&#xff0c;如果喜欢我的文章&#xff0c;可以关注我的公众号「量子前端」&#xff0c;将不定期关注推送前端好文~ 前言 对于页面性能优化&#xff0c;组件懒加载是个比较不错的方案&#xff0c;并且在整个项目打包后&#xff0c;如果未做代码分割&#xff0c;构建出的文…

代理ip的优势、用途及注意事项

随着互联网的高速发展&#xff0c;代理ip的名气和地位也随着水涨船高。那么是什么让它们被我们所知悉的呢&#xff1f;下面我们就代理ip的优势、用途和注意事项来分析一下它为什么能迎合着互联网的发展而壮大自己的。 一、优势 每一个脱颖而出的产品必然有它的优势&#xff0c;…

Axure教程—菜单(中继器)

本文将教大家如何用AXURE中的中继器制作菜单&#xff08;自动折叠其他菜单&#xff09; 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://iuek50.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87854640?spm1001.2014.30…

知识图谱简介

什么是知识图谱&#xff1f; 参考&#xff1a;知识图谱1、知识图谱2 本质上&#xff0c;知识图谱主要目标是用来描述真实世界中存在的各种实体和概念&#xff0c;以及他们之间的关系&#xff0c;因此可以认为是一种语义网络。 主要作用&#xff1a;通过数据&#xff0c;建立图…

智能自动化助力业务升级:探究低代码开发和业务流程自动化

当我们开始探索业务流程自动化&#xff08;BPA&#xff09;时&#xff0c;就证明我们已经真正进入到企业数字化转型的核心领域了——企业越来越关注如何通过创新技术来提高效率、降低成本并实现业务流程的自动化。在这个背景下&#xff0c;低代码开发平台和业务流程自动化成为了…

vue 滚动加载

在 Vue中&#xff0c;如果一个组件是一个 button&#xff0c;那就可以直接调用 input &#xff08;&#xff09;方法&#xff0c;将组件的 button放入到v-ui中。 然而在v-ui中&#xff0c;一个组件可能不止一个 button&#xff0c;而这些 button还需要从浏览器加载到 DOM树中。…