You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.6 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import axios from "axios";
class Request {
// axios 实例
instance;
// 拦截器对象
interceptorsObj;
// * 存放取消请求控制器Map
abortControllerMap;
constructor(config) {
this.instance = axios.create(config);
// * 初始化存放取消请求控制器Map
this.abortControllerMap = new Map();
this.interceptorsObj = config.interceptors;
// 拦截器执行顺序 接口请求 -> 实例请求 -> 全局请求 -> 实例响应 -> 全局响应 -> 接口响应
this.instance.interceptors.request.use(
(res) => {
const controller = new AbortController();
const url = res.url || "";
res.signal = controller.signal;
this.abortControllerMap.set(url, controller);
return res;
},
(err) => err
);
// 使用实例拦截器
this.instance.interceptors.request.use(
this.interceptorsObj?.requestInterceptors,
this.interceptorsObj?.requestInterceptorsCatch
);
this.instance.interceptors.response.use(
this.interceptorsObj?.responseInterceptors,
this.interceptorsObj?.responseInterceptorsCatch
);
// 全局响应拦截器保证最后执行
this.instance.interceptors.response.use(
// 因为我们接口的数据都在res.data下所以我们直接返回res.data
(res) => {
const url = res.config.url || "";
this.abortControllerMap.delete(url);
return res.data;
},
(err) => err
);
}
request(config) {
return new Promise((resolve, reject) => {
// 如果我们为单个请求设置拦截器,这里使用单个请求的拦截器
if (config.interceptors?.requestInterceptors) {
config = config.interceptors.requestInterceptors(config);
}
this.instance
.request(config)
.then((res) => {
// 如果我们为单个响应设置拦截器,这里使用单个响应的拦截器
if (config.interceptors?.responseInterceptors) {
res = config.interceptors.responseInterceptors(res);
}
resolve(res);
})
.catch((err) => {
reject(err);
});
// .finally(() => {})
});
}
/**
* 取消全部请求
*/
cancelAllRequest() {
for (const [, controller] of this.abortControllerMap) {
controller.abort();
}
this.abortControllerMap.clear();
}
/**
* 取消指定的请求
* @param url 待取消的请求URL
*/
cancelRequest(url) {
const urlList = Array.isArray(url) ? url : [url];
for (const _url of urlList) {
this.abortControllerMap.get(_url)?.abort();
this.abortControllerMap.delete(_url);
}
}
}
export default Request;