refactor: 重构 request 提高可读性
parent
3d137333e0
commit
40f1f77d46
|
@ -139,9 +139,9 @@ export interface AxiosRequestConfig
|
||||||
*/
|
*/
|
||||||
transformResponse?: AxiosTransformer | AxiosTransformer[];
|
transformResponse?: AxiosTransformer | AxiosTransformer[];
|
||||||
/**
|
/**
|
||||||
* 异常梳处理
|
* 异常处理
|
||||||
*/
|
*/
|
||||||
errorHandler?: (error: unknown) => Promise<unknown>;
|
errorHandler?: (error: unknown) => Promise<AxiosResponse>;
|
||||||
/**
|
/**
|
||||||
* 监听上传进度
|
* 监听上传进度
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
import { isFunction } from '../helpers/isTypes';
|
||||||
import { isCancel, isCancelToken } from './cancel';
|
import { isCancel, isCancelToken } from './cancel';
|
||||||
import { flattenHeaders } from './flattenHeaders';
|
import { flattenHeaders } from './flattenHeaders';
|
||||||
import { transformData } from './transformData';
|
import { AxiosTransformer, transformData } from './transformData';
|
||||||
import { request } from './request';
|
import { request } from './request';
|
||||||
import { AxiosRequestConfig, AxiosResponse } from './Axios';
|
import { AxiosRequestConfig, AxiosResponse } from './Axios';
|
||||||
import { transformURL } from './transformURL';
|
import { transformURL } from './transformURL';
|
||||||
|
@ -17,37 +18,45 @@ export default function dispatchRequest<TData = unknown>(
|
||||||
config: AxiosRequestConfig,
|
config: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse> {
|
): Promise<AxiosResponse> {
|
||||||
throwIfCancellationRequested(config);
|
throwIfCancellationRequested(config);
|
||||||
|
const { transformRequest, transformResponse } = config;
|
||||||
|
|
||||||
config.method = config.method ?? 'get';
|
|
||||||
config.url = transformURL(config);
|
config.url = transformURL(config);
|
||||||
|
config.method = config.method ?? 'get';
|
||||||
config.headers = flattenHeaders(config);
|
config.headers = flattenHeaders(config);
|
||||||
config.data = transformData(
|
|
||||||
config.data,
|
|
||||||
config.headers,
|
|
||||||
config.transformRequest,
|
|
||||||
);
|
|
||||||
|
|
||||||
function transformer(response: AxiosResponse<TData>) {
|
transform(config, transformRequest);
|
||||||
response.data = transformData(
|
|
||||||
response.data as AnyObject,
|
function onSuccess(response: AxiosResponse<TData>) {
|
||||||
response.headers,
|
throwIfCancellationRequested(config);
|
||||||
config.transformResponse,
|
transform(response, transformResponse);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onError(reason: unknown) {
|
||||||
|
if (!isCancel(reason)) {
|
||||||
|
throwIfCancellationRequested(config);
|
||||||
|
if (isAxiosError(reason)) {
|
||||||
|
transform(reason.response as AxiosResponse<TData>, transformResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFunction(config.errorHandler)) {
|
||||||
|
return config.errorHandler(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transform<TData = unknown>(
|
||||||
|
target: AxiosRequestConfig | AxiosResponse<TData>,
|
||||||
|
transformer?: AxiosTransformer | AxiosTransformer[],
|
||||||
|
) {
|
||||||
|
target.data = transformData(
|
||||||
|
target.data as AnyObject,
|
||||||
|
target.headers,
|
||||||
|
transformer,
|
||||||
) as TData;
|
) as TData;
|
||||||
}
|
}
|
||||||
|
|
||||||
return request<TData>(config)
|
return request<TData>(config).then(onSuccess).catch(onError);
|
||||||
.then((response: AxiosResponse<TData>) => {
|
|
||||||
throwIfCancellationRequested(config);
|
|
||||||
transformer(response);
|
|
||||||
return response;
|
|
||||||
})
|
|
||||||
.catch((reason: unknown) => {
|
|
||||||
if (!isCancel(reason)) {
|
|
||||||
throwIfCancellationRequested(config);
|
|
||||||
if (isAxiosError(reason)) {
|
|
||||||
transformer(reason.response as AxiosResponse<TData>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw config.errorHandler?.(reason) ?? reason;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import { AxiosAdapterRequestType } from '../adapter';
|
import { AxiosAdapterRequestType } from '../adapter';
|
||||||
import { AxiosRequestConfig } from './Axios';
|
import { AxiosRequestConfig } from './Axios';
|
||||||
|
|
||||||
|
const postRE = /^POST$/i;
|
||||||
|
const getRE = /^GET$/i;
|
||||||
|
|
||||||
export function generateType(
|
export function generateType(
|
||||||
config: AxiosRequestConfig,
|
config: AxiosRequestConfig,
|
||||||
): AxiosAdapterRequestType {
|
): AxiosAdapterRequestType {
|
||||||
let requestType: AxiosAdapterRequestType = 'request';
|
let requestType: AxiosAdapterRequestType = 'request';
|
||||||
|
|
||||||
const method = config.method!.toUpperCase();
|
if (config.upload && postRE.test(config.method!)) {
|
||||||
if (config.upload && method === 'POST') {
|
|
||||||
requestType = 'upload';
|
requestType = 'upload';
|
||||||
}
|
} else if (config.download && getRE.test(config.method!)) {
|
||||||
if (config.download && method === 'GET') {
|
|
||||||
requestType = 'download';
|
requestType = 'download';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ export function request<TData = unknown>(
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
assert(isFunction(config.adapter), 'adapter 不是一个 function');
|
assert(isFunction(config.adapter), 'adapter 不是一个 function');
|
||||||
assert(isString(config.url), 'url 不是一个 string');
|
assert(isString(config.url), 'url 不是一个 string');
|
||||||
assert(isString(config.method), 'method 不是一个 string');
|
|
||||||
|
|
||||||
const adapterConfig: AxiosAdapterRequestConfig = {
|
const adapterConfig: AxiosAdapterRequestConfig = {
|
||||||
...config,
|
...config,
|
||||||
|
|
|
@ -7,20 +7,15 @@ import {
|
||||||
} from 'scripts/test.utils';
|
} from 'scripts/test.utils';
|
||||||
|
|
||||||
describe('src/core/request.ts', () => {
|
describe('src/core/request.ts', () => {
|
||||||
test('应该抛出异常', async () => {
|
test('应该抛出异常', () => {
|
||||||
await expect(request({})).rejects.toThrowErrorMatchingInlineSnapshot(
|
expect(request({})).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||||
'"[axios-miniprogram]: adapter 不是一个 function"',
|
'"[axios-miniprogram]: adapter 不是一个 function"',
|
||||||
);
|
);
|
||||||
await expect(
|
expect(
|
||||||
request({ adapter: mockAdapter() }),
|
request({ adapter: mockAdapter() }),
|
||||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||||
'"[axios-miniprogram]: url 不是一个 string"',
|
'"[axios-miniprogram]: url 不是一个 string"',
|
||||||
);
|
);
|
||||||
await expect(
|
|
||||||
request({ adapter: mockAdapter(), url: 'test' }),
|
|
||||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
||||||
'"[axios-miniprogram]: method 不是一个 string"',
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('应该能够取到数据', async () => {
|
test('应该能够取到数据', async () => {
|
||||||
|
|
Loading…
Reference in New Issue