refactor: 重构 request 提高可读性

pull/41/head
zjx0905 2023-04-07 13:50:08 +08:00
parent 3d137333e0
commit 40f1f77d46
5 changed files with 46 additions and 42 deletions

View File

@ -139,9 +139,9 @@ export interface AxiosRequestConfig
*/
transformResponse?: AxiosTransformer | AxiosTransformer[];
/**
*
*
*/
errorHandler?: (error: unknown) => Promise<unknown>;
errorHandler?: (error: unknown) => Promise<AxiosResponse>;
/**
*
*/

View File

@ -1,6 +1,7 @@
import { isFunction } from '../helpers/isTypes';
import { isCancel, isCancelToken } from './cancel';
import { flattenHeaders } from './flattenHeaders';
import { transformData } from './transformData';
import { AxiosTransformer, transformData } from './transformData';
import { request } from './request';
import { AxiosRequestConfig, AxiosResponse } from './Axios';
import { transformURL } from './transformURL';
@ -17,37 +18,45 @@ export default function dispatchRequest<TData = unknown>(
config: AxiosRequestConfig,
): Promise<AxiosResponse> {
throwIfCancellationRequested(config);
const { transformRequest, transformResponse } = config;
config.method = config.method ?? 'get';
config.url = transformURL(config);
config.method = config.method ?? 'get';
config.headers = flattenHeaders(config);
config.data = transformData(
config.data,
config.headers,
config.transformRequest,
);
function transformer(response: AxiosResponse<TData>) {
response.data = transformData(
response.data as AnyObject,
response.headers,
config.transformResponse,
) as TData;
transform(config, transformRequest);
function onSuccess(response: AxiosResponse<TData>) {
throwIfCancellationRequested(config);
transform(response, transformResponse);
return response;
}
return request<TData>(config)
.then((response: AxiosResponse<TData>) => {
throwIfCancellationRequested(config);
transformer(response);
return response;
})
.catch((reason: unknown) => {
function onError(reason: unknown) {
if (!isCancel(reason)) {
throwIfCancellationRequested(config);
if (isAxiosError(reason)) {
transformer(reason.response as AxiosResponse<TData>);
transform(reason.response as AxiosResponse<TData>, transformResponse);
}
}
throw config.errorHandler?.(reason) ?? reason;
});
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;
}
return request<TData>(config).then(onSuccess).catch(onError);
}

View File

@ -1,16 +1,17 @@
import { AxiosAdapterRequestType } from '../adapter';
import { AxiosRequestConfig } from './Axios';
const postRE = /^POST$/i;
const getRE = /^GET$/i;
export function generateType(
config: AxiosRequestConfig,
): AxiosAdapterRequestType {
let requestType: AxiosAdapterRequestType = 'request';
const method = config.method!.toUpperCase();
if (config.upload && method === 'POST') {
if (config.upload && postRE.test(config.method!)) {
requestType = 'upload';
}
if (config.download && method === 'GET') {
} else if (config.download && getRE.test(config.method!)) {
requestType = 'download';
}

View File

@ -44,7 +44,6 @@ export function request<TData = unknown>(
return new Promise((resolve, reject) => {
assert(isFunction(config.adapter), 'adapter 不是一个 function');
assert(isString(config.url), 'url 不是一个 string');
assert(isString(config.method), 'method 不是一个 string');
const adapterConfig: AxiosAdapterRequestConfig = {
...config,

View File

@ -7,20 +7,15 @@ import {
} from 'scripts/test.utils';
describe('src/core/request.ts', () => {
test('应该抛出异常', async () => {
await expect(request({})).rejects.toThrowErrorMatchingInlineSnapshot(
test('应该抛出异常', () => {
expect(request({})).rejects.toThrowErrorMatchingInlineSnapshot(
'"[axios-miniprogram]: adapter 不是一个 function"',
);
await expect(
expect(
request({ adapter: mockAdapter() }),
).rejects.toThrowErrorMatchingInlineSnapshot(
'"[axios-miniprogram]: url 不是一个 string"',
);
await expect(
request({ adapter: mockAdapter(), url: 'test' }),
).rejects.toThrowErrorMatchingInlineSnapshot(
'"[axios-miniprogram]: method 不是一个 string"',
);
});
test('应该能够取到数据', async () => {