Skip to content

Commit

Permalink
fix: 下载进度/上传进度 类型错误
Browse files Browse the repository at this point in the history
  • Loading branch information
zjxxxxxxxxx committed Apr 20, 2023
1 parent 1867273 commit 2d691b6
Show file tree
Hide file tree
Showing 18 changed files with 151 additions and 181 deletions.
10 changes: 5 additions & 5 deletions docs/pages/basics/download.md
Expand Up @@ -71,14 +71,14 @@ axios('https://api.com/test', {
},
onDownloadProgress(event) {
const {
// 下载进度
// 下载进度百分比
progress,

// 已经下载的数据长度
totalBytesSent,
// 已经下载的数据长度,单位 Bytes
totalBytesWritten,

// 预期需要下载的数据总长度
totalBytesExpectedToSend,
// 预预期需要下载的数据总长度,单位 Bytes
totalBytesExpectedToWrite,
} = event;
},
})
Expand Down
6 changes: 3 additions & 3 deletions docs/pages/basics/upload.md
Expand Up @@ -101,13 +101,13 @@ axios('https://api.com/test', {
},
onUploadProgress(event) {
const {
// 上传进度
// 上传进度百分比
progress,

// 已经上传的数据长度
// 已经上传的数据长度,单位 Bytes
totalBytesSent,

// 预期需要上传的数据总长度
// 预期需要上传的数据总长度,单位 Bytes
totalBytesExpectedToSend,
} = event;
},
Expand Down
31 changes: 30 additions & 1 deletion docs/pages/guide/quick-start.md
Expand Up @@ -80,7 +80,6 @@ axios('test');
const {
// 静态对象
// 注意:默认导出的 axios 在 CommonJS 里是以 default 属性的方式存在
// import axios from 'axios-miniprogram' 等于 const axios = require('axios-miniprogram').default
default: axios,

// 取消令牌
Expand Down Expand Up @@ -125,6 +124,36 @@ const {

::::

不同的模块系统存在一些小差异,`esm` 会自动处理默认导入,但 `cjs` 不会处理默认导入。

```ts
// 默认导入,esm 和 cjs 这两种写法是等价关系
import axios from 'axios-miniprogram';
const axios = require('axios-miniprogram').default;

// 别名导入,esm 和 cjs 这两种写法是等价关系
import * as axios from 'axios-miniprogram';
const axios = require('axios-miniprogram');

// 具名导入,esm 和 cjs 这两种写法是等价关系
import {
default as axios,
CancelToken,
isCancel,
Axios,
isAxiosError,
createAdapter,
} from 'axios-miniprogram';
const {
default: axios,
CancelToken,
isCancel,
Axios,
isAxiosError,
createAdapter,
} = require('axios-miniprogram');
```

## 使用

### `axios(url, config?)`
Expand Down
10 changes: 8 additions & 2 deletions scripts/test.utils.ts
Expand Up @@ -113,8 +113,14 @@ export function mockAdapterFail(options: MockAdapterOptions = {}) {
return mockAdapterBase('fail', options);
}

export const testEachMethods = test.each([
export const methods = [
...requestMethodNames,
...requestMethodWithParamsNames,
...requestMethodWithDataNames,
]);
];

export const testEachMethods = test.each(methods);

export function eachMethods(cb: (k: (typeof methods)[number]) => void) {
methods.forEach(cb);
}
6 changes: 3 additions & 3 deletions src/adapter.ts
@@ -1,7 +1,7 @@
import { isFunction, isPlainObject } from './helpers/isTypes';
import { assert } from './helpers/error';
import {
AxiosProgressCallback,
AxiosProgressEvent,
AxiosRequestFormData,
AxiosRequestHeaders,
} from './core/Axios';
Expand Down Expand Up @@ -229,8 +229,8 @@ export type AxiosAdapterPlatformTask =
| void
| {
abort?(): void;
onProgressUpdate?(callback: AxiosProgressCallback): void;
offProgressUpdate?(callback: AxiosProgressCallback): void;
onProgressUpdate?(callback: (event: AxiosProgressEvent) => void): void;
offProgressUpdate?(callback: (event: AxiosProgressEvent) => void): void;
};

/**
Expand Down
118 changes: 67 additions & 51 deletions src/core/Axios.ts
@@ -1,7 +1,7 @@
import { buildURL } from '../helpers/buildURL';
import { isAbsoluteURL } from '../helpers/isAbsoluteURL';
import { combineURL } from '../helpers/combineURL';
import { isFunction, isPromise, isString } from '../helpers/isTypes';
import { isString } from '../helpers/isTypes';
import {
AxiosAdapter,
AxiosAdapterRequestMethod,
Expand Down Expand Up @@ -102,33 +102,55 @@ export type AxiosRequestData =
export type AxiosResponseData = number | AxiosAdapterResponseData;

/**
* 监听进度回调事件对象
* 进度对象
*/
export interface AxiosProgressEvent {
export interface AxiosProgressEvent extends AnyObject {
/**
* 下载进度
* 上传进度百分比
*/
progress: number;
}

/**
* 下载进度对象
*/
export interface AxiosDownloadProgressEvent extends AxiosProgressEvent {
/**
* 已经下载的数据长度,单位 Bytes
*/
totalBytesWritten: number;
/**
* 预预期需要下载的数据总长度,单位 Bytes
*/
totalBytesExpectedToWrite: number;
}

/**
* 监听下载进度
*/
export interface AxiosDownloadProgressCallback {
(event: AxiosDownloadProgressEvent): void;
}

/**
* 上传进度对象
*/
export interface AxiosUploadProgressEvent extends AxiosProgressEvent {
/**
* 已经下载的数据长度
* 已经上传的数据长度,单位 Bytes
*/
totalBytesSent: number;
/**
* 预期需要下载的数据总长度
* 预期需要上传的数据总长度,单位 Bytes
*/
totalBytesExpectedToSend: number;
}

/**
* 监听进度回调
* 监听上传进度
*/
export interface AxiosProgressCallback {
(
/**
* 事件对象
*/
event: AxiosProgressEvent,
): void;
export interface AxiosUploadProgressCallback {
(event: AxiosUploadProgressEvent): void;
}

/**
Expand Down Expand Up @@ -197,15 +219,15 @@ export interface AxiosRequestConfig
/**
* 错误处理
*/
errorHandler?: (error: unknown) => Promise<void> | void;
errorHandler?: (error: unknown) => Promise<AxiosResponse>;
/**
* 监听上传进度
* 监听下载进度
*/
onUploadProgress?: AxiosProgressCallback;
onDownloadProgress?: AxiosUploadProgressCallback;
/**
* 监听下载进度
* 监听上传进度
*/
onDownloadProgress?: AxiosProgressCallback;
onUploadProgress?: AxiosUploadProgressCallback;
}

/**
Expand Down Expand Up @@ -321,40 +343,34 @@ export default class Axios extends AxiosDomain {
};

#processRequest(config: AxiosRequestConfig) {
const chain: [
Interceptor<AxiosRequestConfig> | Interceptor<AxiosResponse>,
] = [
{
resolved: dispatchRequest,
},
];

this.interceptors.request.forEach(chain.unshift.bind(chain));
this.interceptors.response.forEach(chain.push.bind(chain));

let next = Promise.resolve(config);
for (const { resolved, rejected } of chain) {
next = next.then(
// @ts-ignore
resolved,
rejected,
);
}
const requestHandler = {
resolved: dispatchRequest,
};
const errorHandler = {
rejected: config.errorHandler,
};
const chain: (
| Partial<Interceptor<AxiosRequestConfig>>
| Partial<Interceptor<AxiosResponse>>
)[] = [];

// 错误处理
next = next.catch((reason) => {
const { errorHandler } = config;

if (isFunction(errorHandler)) {
const promise = errorHandler(reason);
if (isPromise(promise)) {
return promise.then(() => Promise.reject(reason));
}
}

return Promise.reject(reason);
this.interceptors.request.forEach((requestInterceptor) => {
chain.unshift(requestInterceptor);
});
chain.push(requestHandler);
this.interceptors.response.forEach((responseInterceptor) => {
chain.push(responseInterceptor);
});
chain.push(errorHandler);

return next as Promise<AxiosResponse>;
return chain.reduce(
(next, { resolved, rejected }) =>
next.then(
// @ts-ignore
resolved,
rejected,
),
Promise.resolve(config),
) as Promise<AxiosResponse>;
}
}
9 changes: 2 additions & 7 deletions src/core/request.ts
Expand Up @@ -6,12 +6,7 @@ import {
AxiosAdapterResponseError,
AxiosAdapterPlatformTask,
} from '../adapter';
import {
AxiosProgressCallback,
AxiosRequestConfig,
AxiosResponse,
AxiosResponseError,
} from './Axios';
import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios';
import { isCancelToken } from './cancel';
import { AxiosErrorResponse, createError } from './createError';
import { generateType } from './generateType';
Expand Down Expand Up @@ -103,7 +98,7 @@ export function request(config: AxiosRequestConfig) {

function tryToggleProgressUpdate(
adapterConfig: AxiosAdapterRequestConfig,
adapterProgress?: (callback: AxiosProgressCallback) => void,
adapterProgress?: (cb: (event: AnyObject) => void) => void,
) {
const { onUploadProgress, onDownloadProgress } = adapterConfig;
if (isFunction(adapterProgress)) {
Expand Down
7 changes: 0 additions & 7 deletions src/helpers/isTypes.ts
Expand Up @@ -30,10 +30,3 @@ export function isDate(date: any): date is Date {
export function isFunction<T extends Function>(value: any): value is T {
return typeof value === 'function';
}

export function isPromise<T = unknown>(value: any): value is Promise<T> {
return (
_toString.call(value) === '[object Promise]' ||
(isPlainObject(value) && isFunction(value.then))
);
}
6 changes: 4 additions & 2 deletions src/index.ts
Expand Up @@ -9,8 +9,10 @@ export type {
AxiosResponse,
AxiosResponseData,
AxiosResponseError,
AxiosProgressEvent,
AxiosProgressCallback,
AxiosDownloadProgressEvent,
AxiosDownloadProgressCallback,
AxiosUploadProgressEvent,
AxiosUploadProgressCallback,
} from './core/Axios';
export type {
AxiosAdapter,
Expand Down
12 changes: 2 additions & 10 deletions test/axios.api.test.ts
Expand Up @@ -2,14 +2,10 @@ import { describe, test, expect } from 'vitest';
import Axios from '@/core/Axios';
import { CancelToken, isCancel } from '@/core/cancel';
import { isAxiosError } from '@/core/createError';
import {
requestMethodNames,
requestMethodWithDataNames,
requestMethodWithParamsNames,
} from '@/core/AxiosDomain';
import { createAdapter } from '@/adapter';
import axios from '@/axios';
import defaults from '@/defaults';
import { eachMethods } from 'scripts/test.utils';

describe('src/axios.ts', () => {
test('应该有这些静态属性', () => {
Expand All @@ -35,11 +31,7 @@ describe('src/axios.ts', () => {
expect(instance.fork).toBeTypeOf('function');
expect(instance.request).toBeTypeOf('function');

[
...requestMethodNames,
...requestMethodWithParamsNames,
...requestMethodWithDataNames,
].forEach((k) => {
eachMethods((k) => {
expect(instance[k]).toBeTypeOf('function');
});
});
Expand Down
16 changes: 4 additions & 12 deletions test/axios.instance.test.ts
@@ -1,11 +1,7 @@
import { describe, test, expect } from 'vitest';
import {
requestMethodNames,
requestMethodWithDataNames,
requestMethodWithParamsNames,
} from '@/core/AxiosDomain';
import axios from '@/axios';
import defaults from '@/defaults';
import { testEachMethods } from 'scripts/test.utils';

describe('src/axios.ts', () => {
test('应该有这些实例属性及方法', () => {
Expand All @@ -14,13 +10,9 @@ describe('src/axios.ts', () => {
expect(axios.getUri).toBeTypeOf('function');
expect(axios.fork).toBeTypeOf('function');
expect(axios.request).toBeTypeOf('function');
});

[
...requestMethodNames,
...requestMethodWithParamsNames,
...requestMethodWithDataNames,
].forEach((k) => {
expect(axios[k]).toBeTypeOf('function');
});
testEachMethods('%s 应该是一个函数', (k) => {
expect(axios[k]).toBeTypeOf('function');
});
});

0 comments on commit 2d691b6

Please sign in to comment.