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

news/2024/5/20 1:18:02 标签: 前端, axios, TS, 封装, 配置


目 录

  • 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.niftyadmin.cn/n/387953.html

相关文章

SpringCloudAlibaba:服务网关之Gateway学习

目录 一、网关简介 &#xff08;一&#xff09;为什么要用网关 &#xff08;二&#xff09;网关解决了什么问题 &#xff08;三&#xff09;常用的网关 二、Gateway简介 &#xff08;一&#xff09;核心概念 &#xff08;二&#xff09;工作原理 三、Gateway快速入门 &…

LEAP软件操作基础/安装与注册/基本原理和数据结构

本次内容突出与实例结合&#xff0c;紧密结合国家能源统计制度及《省级温室气体排放编制指南》&#xff0c;深入浅出地介绍针对不同级别研究对象时如何根据数据结构、可获取性、研究目的&#xff0c;构建合适的能源生产、转换、消费、温室气体排放&#xff08;以碳排放为主&…

滴滴和华为5年,分享一下真实的划水经验....

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入华为&#xff0c;之后跳槽到了滴滴&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是5年的工作经验吧。 这5年之间完成了一次晋升&#xff0c;换了一家公司&#xff0c;有…

SpringBatch的两种实现方式: Tasklet 和 Chunk

直接上代码 ■ 共通部分&#xff1a; 1. 代码结构 2. pom.xml <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.versi…

VMware ESXi 8.0U1a macOS Unlocker OEM BIOS (标准版和厂商定制版)

VMware ESXi 8.0 Update 1a macOS Unlocker & OEM BIOS (标准版和厂商定制版) ESXi 8.0U1 标准版&#xff0c;Dell HPE 联想 浪潮 定制版 请访问原文链接&#xff1a; https://sysin.org/blog/vmware-esxi-8-u1-oem/&#xff0c;查看最新版。原创作品&#xff0c;转载请保…

黑客零基础从入门到精通学习成长路线(超多图、非常详细),看完这一篇就够了

前言 近几年&#xff0c;随着移动互联网、大数据、云计算、人工智能等新一代信息技术的快速发展&#xff0c;围绕网络和数据的服务与应用呈现爆发式增长&#xff0c;丰富的应用场景下暴露出越来越多的网络安全风险和问题。 但是&#xff0c;我国网络安全整体投入不高。网络安…

LwIP 之七 详解 PBUF 结构、通信数据流、性能优化

数据包的复制在协议栈中是非常耗时的一个操作。LwIP 协议栈内部使用 pbuf 这种数据结构来对数据进行传递&#xff0c;灵活的 pbuf 结构体使得数据在不同网络层之间传递时可以减少内存的开销&#xff0c;避免频繁的内存复制&#xff0c;增加数据在不同层之间传递的速度。 简介 …

ffmpeg之AVFrame结构体详细解释

AVFrame 结构体是 FFmpeg 中用于描述媒体数据帧&#xff08;视频、音频等&#xff09;的结构体。它包含了媒体数据帧的各种参数和数据信息&#xff0c;是进行媒体数据的编解码和处理的必要元素。下面是关于 AVFrame 结构体的详细介绍&#xff0c;同时也给出一个简单的代码示例。…