赞
踩
index.ts /* `AxiosResponse`:是Axios库中定义的响应对象的类型, 用于表示服务器返回的响应数据, 包含属性:data、status、statusText、headers、config、request。 */ import axios, { AxiosResponse } from 'axios' /* `InternalAxiosRequestConfig`:这是一个接口,它继承了`AxiosRequestConfig`接口,并且额外定义了一个`headers`属性 用于规范 axios 的请求配置, */ /* `AxiosInstance`:Axios实例的类型 */ import type { AxiosInstance, InternalAxiosRequestConfig } from 'axios' import type { RequestInterceptors, CreateRequestConfig, RequestConfig, } from './types' class Request { // axios实例 instance: AxiosInstance // 拦截器对象 interceptorsObj?: RequestInterceptors<AxiosResponse> // 存放取消请求控制器Map abortControllerMap: Map<string, AbortController> constructor(config: CreateRequestConfig) { this.instance = axios.create(config) this.interceptorsObj = config.interceptors // 初始化存放取消请求控制器Map this.abortControllerMap = new Map() // 拦截器执行顺序 接口请求 -> 实例请求 -> 全局请求 -> 实例响应 -> 全局响应 -> 接口响应 /* 为什么,这里有两个`this.instance.interceptors.request.use`和两个`this.instance.interceptors.response.use`方法调用, 因为,Axios提供了一种机制来添加拦截器,在发送请求、接收响应的过程中,执行一些额外的逻辑。 每个`interceptors.request.use`方法调用,都用于添加一个`请求拦截器`,它会在发送请求之前执行一些逻辑, 每个`interceptors.response.use`方法调用,都用于添加个`响应拦截器`,它会在接收到响应之后执行一些逻辑。 第一个`this.instance.interceptors.request.use`方法调用,用于添加一个请求拦截器, 它的逻辑是:创建一个`AbortController`实例,给请求配置对象中添加`signal`属性,并将`该请求的URL`和对应的`AbortController`实例存储到`abortControllerMap`中。 第二个`this.instance.interceptors.request.use`方法调用,是使用实例拦截器, 它的逻辑是:将在`config.interceptors`对象中定义的请求拦截器函数,作为参数传递给 `request.use` 方法。 第一个`this.instance.interceptors.response.use`方法调用,用于添加一个响应拦截器, 它的逻辑是:在接收到响应后从`res`对象中,取出响应的数据,并从`abortControllerMap`中删除对应的URL。 第二个`this.instance.interceptors.response.use`方法调用,是使用实例拦截器, 它的逻辑是:将在`config.interceptors`对象中定义的响应拦截器函数,作为参数传递给 `response.use` 方法。 通过添加拦截器,可以在请求和响应的不同阶段执行一些通用的逻辑,例如添加请求头、处理错误、修改请求或响应数据等。 */ this.instance.interceptors.request.use( (config: InternalAxiosRequestConfig) => { const controller = new AbortController() const url = config.url || '' config.signal = controller.signal this.abortControllerMap.set(url, controller) return config }, (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, ) // 全局响应拦截器保证最后执行 // Axios的响应对象,包括config对象、data对象、headers对象、request对象、status状态码、statusText字符串 this.instance.interceptors.response.use( // 因为,我们接口的数据都在res.data下,所以我们直接返回res.data (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(config) 是使用 Axios 实例发送 HTTP 请求的方法, this.instance是一个Axios实例,通过调用 request(config) 方法可以发送HTTP请求, config 参数是一个`AxiosRequestConfig`对象,用于配置请求的相关参数,例如请求的 URL、请求方法、请求头、请求体等。 Axios提供了多种方法用于发送不同类型的请求,例如 get()、post()、put() 等,但它们都是通过调用 request(config) 方法实现的, request(config) 方法可以接收一个 AxiosRequestConfig 对象作为参数,该对象包含了发送请求所需的所有配置信息,然后返回一个 Promise 对象,用于处理请求的响应。 所以,this.instance.request(config) 表示使用 Axios 实例发送一个 HTTP 请求,并传入配置参数 config。 */ this.instance .request<any, T>(config) .then(res => { // 如果我们为单个响应设置拦截器,这里使用单个响应的拦截器 if (config.interceptors?.responseInterceptors) { res = config.interceptors.responseInterceptors(res) } resolve(res) }) .catch((err: any) => { reject(err) }) .finally(() => {}) }) } /* 取消全部请求 for (const [, controller] of controllerMap) 表示只获取 Map 中的值,而不获取键 */ 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) } } } export default Request export { RequestConfig, RequestInterceptors }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。