TS 封装多功能网络请求库 AXIOS 最终业务版

本文接上文 <封装简易 AXIOS 请求库全流程> , 如果对此文章感兴趣可以站内搜索查看下。
这里就不再多赘述封装的好处,这篇文章将会对幼年封装 axios 版进一步改造。

当前分享的代码基于 “axios”: “^1.6.8”

封装后的 AXIOS 将会拥有以下功能

  1. 拦截器增强,拥有三种拦截模式
    • 全局拦截
    • 实例拦截
    • 连接拦截
  2. 实例增强,一个项目可以拥有多个 AXIOS 实例
  3. 类型增强,使用 TypeScript 改造之前封装的简易版 AXIOS
  4. 正确处理 Promise 类型,方便调用时通过泛型传入类型

核心代码共享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import axios from "axios";

import type { AxiosInstance } from "axios";
import type { DevReqAxiosRequestConfig } from "./type";

//全局拦截器,实例拦截器,连接拦截器

class devReqClass {
instance: AxiosInstance;

constructor(config: DevReqAxiosRequestConfig) {
this.instance = axios.create(config);
axios.post;
//全局拦截器
//全局请求拦截
this.instance.interceptors.request.use(
config => {
return config;
},
err => {
return err;
}
);

//全局响应拦截
this.instance.interceptors.response.use(
res => {
return res.data;
},
err => {
return err;
}
);

//实例拦截器
if (config.interceptors) {
this.instance.interceptors.request.use(
config.interceptors.reqSucess,
config.interceptors.reqError
);
this.instance.interceptors.response.use(
config.interceptors.respSucess,
config.interceptors.respError
);
}
}

request<T>(config: DevReqAxiosRequestConfig<T>) {
//连接请求拦截器
if (config.interceptors?.reqSucess) {
config = config.interceptors.reqSucess(config as any);
}

//默认Promise没有类型,为了兼容。需要从外面传进类型。
//连接响应拦截器
return new Promise<T>((resolve, reject) => {
this.instance
.request<any, T>(config)
.then(res => {
if (config.interceptors?.respSucess) {
res = config.interceptors.respSucess(res);
}
resolve(res);
})
.catch(err => {
if (config.interceptors?.respError) {
err = config.interceptors.respError(err);
}
reject(err);
});
});
}

get<T = any>(config: DevReqAxiosRequestConfig<T>) {
return this.request({ ...config, method: "GET" });
}

post<T = any>(config: DevReqAxiosRequestConfig<T>) {
return this.request({ ...config, method: "POST" });
}

path<T = any>(config: DevReqAxiosRequestConfig<T>) {
return this.request({ ...config, method: "PATCH" });
}

delete<T = any>(config: DevReqAxiosRequestConfig<T>) {
return this.request({ ...config, method: "DELETE" });
}
}

export default devReqClass;

实例拦截器用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//实例2
export const devReq2 = new devReqClass({
baseURL: "http://127.0.0.1:8000",
timeout: 5000,
interceptors: {
reqSucess(config) {
console.log("实例请求被我拦截了");
return config;
},
respSucess(response) {
console.log("实例响应被我拦截了");
return response;
},
},
});

连接拦截器用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
interface IHome {
data: object;
returnCode: string;
success: boolean;
}

export const fetchHome2 = () => {
return devReq2.request<IHome>({
url: "/home/multidata",
interceptors: {
reqSucess(config) {
console.log("子链接的请求被我拦截了");
return config;
},
respSucess(res) {
console.log("子链接的响应被我拦截了");
return res;
},
},
});
};