You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.3 KiB
104 lines
3.3 KiB
import axios, { type AxiosResponse, AxiosInstance, InternalAxiosRequestConfig } from 'axios'
|
|
import { addPrefixByRecursive } from '@/utils/utils'
|
|
import type { RequestConfig, RequestInterceptors, CreateRequestConfig } from './types'
|
|
|
|
export default class Request {
|
|
// axios 实例
|
|
instance: AxiosInstance
|
|
// 拦截器对象
|
|
interceptorsObj?: RequestInterceptors<AxiosResponse>
|
|
// * 存放取消请求控制器Map
|
|
abortControllerMap: Map<string, AbortController>
|
|
|
|
constructor(config: CreateRequestConfig) {
|
|
this.instance = axios.create(config)
|
|
//取消请求控制器Map
|
|
this.abortControllerMap = new Map()
|
|
this.interceptorsObj = config.interceptors
|
|
// 拦截器执行顺序 接口请求 -> 实例请求 -> 全局请求 -> 实例响应 -> 全局响应 -> 接口响应
|
|
this.instance.interceptors.request.use(
|
|
(res: InternalAxiosRequestConfig) => {
|
|
const controller = new AbortController()
|
|
const url = res.url || ''
|
|
res.signal = controller.signal
|
|
this.abortControllerMap.set(url, controller)
|
|
return res
|
|
},
|
|
(err: any) => 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: AxiosResponse) => {
|
|
const url = res.config.url || ''
|
|
this.abortControllerMap.delete(url)
|
|
return res.data
|
|
},
|
|
(err: any) => err
|
|
)
|
|
}
|
|
request<T>(config: RequestConfig<T>): Promise<T> {
|
|
return new Promise((resolve, reject) => {
|
|
if (config.interceptors?.requestInterceptors) {
|
|
config = config.interceptors.requestInterceptors(config as any)
|
|
}
|
|
this.instance
|
|
.request<any, T>(config)
|
|
.then(res => {
|
|
// 如果为单个响应设置拦截器,使用单个响应的拦截器
|
|
if (config.interceptors?.responseInterceptors) {
|
|
res = config.interceptors.responseInterceptors(res)
|
|
}
|
|
|
|
resolve(res)
|
|
})
|
|
.catch((err: any) => {
|
|
reject(err)
|
|
})
|
|
})
|
|
}
|
|
/**
|
|
* 取消全部请求
|
|
*/
|
|
cancelAllRequest() {
|
|
for (const [, controller] of this.abortControllerMap) {
|
|
controller.abort()
|
|
}
|
|
this.abortControllerMap.clear()
|
|
}
|
|
/**
|
|
* 取消指定的请求
|
|
* @param url 待取消的请求URL
|
|
*/
|
|
cancelRequest(url: string | string[]) {
|
|
const urlList = Array.isArray(url) ? url : [url]
|
|
for (const _url of urlList) {
|
|
this.abortControllerMap.get(_url)?.abort()
|
|
this.abortControllerMap.delete(_url)
|
|
}
|
|
}
|
|
}
|
|
|
|
const _request = new Request({
|
|
timeout: 10000,
|
|
timeoutErrorMessage: '网络超时',
|
|
interceptors: {
|
|
responseInterceptors(config) {
|
|
const isJson = /.json$/.test(config.config.url as string)
|
|
isJson && addPrefixByRecursive(config.data.data)
|
|
return config
|
|
}
|
|
}
|
|
})
|
|
export type Response<T> = {
|
|
msg: string
|
|
data: T
|
|
code: number
|
|
}
|
|
|
|
export const request = <T = any>(config: RequestConfig<Response<T>>) => _request.request(config)
|
|
export const cancelRequest = (url: string | string[]) => _request.cancelRequest(url)
|
|
export const cancelAllRequest = () => _request.cancelAllRequest()
|
|
|