import type { AxiosRequestConfig, Canceler } from 'axios'; import axios from 'axios'; import { isFunction } from '/@/utils/is'; // Used to store the identification and cancellation function of each request let pendingMap = new Map<string, Canceler>(); export const getPendingUrl = (config: AxiosRequestConfig) => [config.method, config.url].join('&'); export class AxiosCanceler { /** * Add request * @param {Object} config */ addPending(config: AxiosRequestConfig) { this.removePending(config); const url = getPendingUrl(config); config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => { if (!pendingMap.has(url)) { // If there is no current request in pending, add it pendingMap.set(url, cancel); } }); } /** * @description: Clear all pending */ removeAllPending() { pendingMap.forEach((cancel) => { cancel && isFunction(cancel) && cancel(); }); pendingMap.clear(); } /** * Removal request * @param {Object} config */ removePending(config: AxiosRequestConfig) { const url = getPendingUrl(config); if (pendingMap.has(url)) { // If there is a current request identifier in pending, // the current request needs to be cancelled and removed const cancel = pendingMap.get(url); cancel && cancel(url); pendingMap.delete(url); } } /** * @description: reset */ reset(): void { pendingMap = new Map<string, Canceler>(); } } 这是做什么的
时间: 2024-04-18 20:27:58 浏览: 20
这段代码是一个用于管理取消 Axios 请求的辅助工具类。它包含了以下功能:
1. `addPending(config: AxiosRequestConfig)`: 添加请求到待取消列表中。它会根据请求的方法和 URL 生成一个唯一的标识,并将该标识和取消函数存储在 `pendingMap` 中。
2. `removeAllPending()`: 清除所有待取消的请求。它会遍历 `pendingMap` 中的所有取消函数,并执行它们,然后清空 `pendingMap`。
3. `removePending(config: AxiosRequestConfig)`: 从待取消列表中移除指定的请求。它会根据请求的方法和 URL 生成标识,并从 `pendingMap` 中获取对应的取消函数,然后执行该函数并将其从 `pendingMap` 中删除。
4. `reset()`: 重置待取消列表。它会将 `pendingMap` 重置为空的 Map。
这个工具类的主要作用是在发送请求之前添加请求到待取消列表中,然后根据需要进行取消或清除请求。这在处理页面跳转或组件卸载时非常有用,可以避免因为未完成的请求导致的问题。
相关问题
axios-miniprogram Canceler 应如何导入
要在小程序中使用 `axios-miniprogram` 的 `Canceler` 类,需要先安装 `axios-miniprogram` 包。可以使用以下命令进行安装:
```
npm install axios-miniprogram --save
```
然后,在需要使用 `Canceler` 的地方,可以按照以下方式导入:
```javascript
import { Canceler } from 'axios-miniprogram';
```
然后就可以使用 `Canceler` 类来创建一个取消请求的对象。例如:
```javascript
const cancelToken = axios.CancelToken;
const canceler = new cancelToken.source();
```
这里的 `cancelToken` 是 `axios-miniprogram` 中的一个工厂函数,用于创建 `CancelToken` 类的实例。`canceler` 则是一个 `CancelToken` 类的实例,用于创建取消请求的对象。
基于TypeScript从零重构axios
好的,让我们开始重构axios!
首先,我们需要安装TypeScript和相关的依赖。运行以下命令:
```
npm install typescript @types/node @types/qs @types/form-data
```
接下来,我们需要创建一个tsconfig.json文件。在项目根目录下创建一个名为tsconfig.json的文件,并将以下内容复制到其中:
```json
{
"compilerOptions": {
"lib": ["es6", "dom"],
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"sourceMap": true,
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"exclude": ["node_modules"]
}
```
现在,我们可以开始重构axios的代码了。
首先,我们需要将axios的代码转换为TypeScript。我们可以将所有的JavaScript文件重命名为.ts文件,并使用TypeScript的语法更新代码。例如,我们可以使用类型注释来定义函数的参数类型和返回类型。
下面是一个使用TypeScript语法重构的示例:
```typescript
import * as http from 'http';
import * as https from 'https';
import * as url from 'url';
import * as zlib from 'zlib';
import { Cancel, CancelToken } from './cancel';
import { isFormData } from './utils';
import settle from './core/settle';
import buildURL from './helpers/buildURL';
import parseHeaders from './helpers/parseHeaders';
import createError from './core/createError';
import enhanceError from './core/enhanceError';
import defaults from './defaults';
interface AxiosRequestConfig {
url?: string;
method?: string;
baseURL?: string;
headers?: any;
params?: any;
data?: any;
timeout?: number;
withCredentials?: boolean;
responseType?: XMLHttpRequestResponseType;
xsrfCookieName?: string;
xsrfHeaderName?: string;
onDownloadProgress?: (progressEvent: any) => void;
onUploadProgress?: (progressEvent: any) => void;
cancelToken?: CancelToken;
}
interface AxiosResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: any;
config: AxiosRequestConfig;
request?: any;
}
interface AxiosError<T = any> extends Error {
config: AxiosRequestConfig;
code?: string;
request?: any;
response?: AxiosResponse<T>;
isAxiosError: boolean;
}
interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> {}
interface Axios {
defaults: AxiosRequestConfig;
interceptors: {
request: AxiosInterceptorManager<AxiosRequestConfig>;
response: AxiosInterceptorManager<AxiosResponse>;
};
request<T = any>(config: AxiosRequestConfig): AxiosPromise<T>;
get<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
delete<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
head<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
options<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;
}
interface AxiosInstance extends Axios {
<T = any>(config: AxiosRequestConfig): AxiosPromise<T>;
<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;
}
interface AxiosStatic extends AxiosInstance {
create(config?: AxiosRequestConfig): AxiosInstance;
CancelToken: CancelTokenStatic;
Cancel: CancelStatic;
isCancel: (value: any) => boolean;
}
interface AxiosInterceptorManager<T> {
use(resolved: ResolvedFn<T>, rejected?: RejectedFn): number;
eject(id: number): void;
}
interface ResolvedFn<T> {
(val: T): T | Promise<T>;
}
interface RejectedFn {
(error: any): any;
}
interface CancelToken {
promise: Promise<Cancel>;
reason?: Cancel;
throwIfRequested(): void;
}
interface Canceler {
(message?: string): void;
}
interface CancelExecutor {
(cancel: Canceler): void;
}
interface CancelTokenSource {
token: CancelToken;
cancel: Canceler;
}
interface CancelTokenStatic {
new (executor: CancelExecutor): CancelToken;
source(): CancelTokenSource;
}
interface Cancel {
message?: string;
}
interface CancelStatic {
new (message?: string): Cancel;
}
function axios<T = any>(config: AxiosRequestConfig): AxiosPromise<T> {
return dispatchRequest(config);
}
function createInstance(config: AxiosRequestConfig): AxiosInstance {
const context = new Axios(config);
const instance = Axios.prototype.request.bind(context);
Object.assign(instance, Axios.prototype, context);
return instance as AxiosInstance;
}
const axiosInstance = createInstance(defaults);
axiosInstance.create = function create(config) {
return createInstance(Object.assign(defaults, config));
};
function getDefaultAdapter() {
let adapter;
if (typeof XMLHttpRequest !== 'undefined') {
adapter = require('./adapters/xhr');
} else if (typeof http !== 'undefined') {
adapter = require('./adapters/http');
} else if (typeof https !== 'undefined') {
adapter = require('./adapters/http');
}
return adapter;
}
function dispatchRequest<T = any>(config: AxiosRequestConfig): AxiosPromise<T> {
throwIfCancellationRequested(config.cancelToken);
processConfig(config);
return getDefaultAdapter()(config).then((response) => {
return transformResponseData(response);
}, (error) => {
if (error && error.response) {
error.response = transformResponseData(error.response);
}
return Promise.reject(error);
}).then((response) => {
settle(resolve, reject, response);
return response;
}, (error) => {
settle(resolve, reject, enhanceError(error));
return Promise.reject(enhanceError(error));
});
}
function processConfig(config: AxiosRequestConfig): void {
config.url = transformURL(config);
config.headers = transformHeaders(config);
config.data = transformData(config);
config.params = transformParams(config);
}
function transformURL(config: AxiosRequestConfig): string {
const { url, params, baseURL } = config;
return buildURL(url!, params, baseURL);
}
function transformHeaders(config: AxiosRequestConfig): any {
const { headers = {}, data } = config;
return Object.assign(headers.common || {}, headers[config.method!] || {}, headers, data ? data.headers : null);
}
function transformData(config: AxiosRequestConfig): any {
const { data } = config;
return isFormData(data) ? data : JSON.stringify(data);
}
function transformParams(config: AxiosRequestConfig): any {
const { params } = config;
return params ? params : null;
}
function transformResponseData(response: AxiosResponse): AxiosResponse {
response.data = transformData(response);
response.headers = parseHeaders(response.headers, response.config);
response.data = transformData(response);
return response;
}
function throwIfCancellationRequested(cancelToken?: CancelToken): void {
if (cancelToken) {
cancelToken.throwIfRequested();
}
}
export default axiosInstance;
```
现在我们已经将axios的代码转换为了TypeScript,接下来我们需要更新一下项目的结构。
我们可以将所有的TypeScript代码放在一个src目录下,并将编译后的JavaScript代码放在一个dist目录下。这样做可以使我们的代码更加结构化和易于管理。
接下来,我们需要更新package.json文件中的scripts字段,以便使用TypeScript编译我们的代码。在scripts字段中添加以下内容:
```json
"scripts": {
"build": "tsc"
}
```
现在我们可以运行npm run build命令来编译我们的代码了。
最后,我们需要更新我们的引用代码,以便使用重构后的axios。例如,我们可以使用以下代码来发送一个GET请求:
```typescript
import axios from './dist/axios';
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
```
这就是使用TypeScript从零重构axios的过程。