Merge pull request #21 from fluffff/adapter

refactor: 优化 adapter
pull/22/head
初秋 2021-05-30 14:12:19 +08:00 committed by GitHub
commit 7350371e12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 65 deletions

View File

@ -20,7 +20,7 @@ export interface AxiosStatic extends AxiosInstance {
Axios: AxiosConstructor; Axios: AxiosConstructor;
CancelToken: CancelTokenConstructor; CancelToken: CancelTokenConstructor;
create(defaults?: AxiosRequestConfig): AxiosInstance; create(defaults?: AxiosRequestConfig): AxiosInstance;
createAdapter(platform: AxiosPlatform): AxiosAdapter | undefined; createAdapter(platform: AxiosPlatform): AxiosAdapter;
isCancel(value: any): boolean; isCancel(value: any): boolean;
} }

View File

@ -1,7 +1,7 @@
import { buildURL } from '../helpers/url'; import { buildURL } from '../helpers/url';
import { mergeConfig } from './mergeConfig'; import { mergeConfig } from './mergeConfig';
import { import {
AdapterRequestMethod, AxiosAdapterRequestMethod,
AxiosAdapter, AxiosAdapter,
AxiosAdapterTask, AxiosAdapterTask,
} from './adapter'; } from './adapter';
@ -20,7 +20,9 @@ export type AxiosRequestMethodAlias =
| 'trace' | 'trace'
| 'connect'; | 'connect';
export type AxiosRequestMethod = AdapterRequestMethod | AxiosRequestMethodAlias; export type AxiosRequestMethod =
| AxiosAdapterRequestMethod
| AxiosRequestMethodAlias;
export type AxiosRequestHeaders = AnyObject; export type AxiosRequestHeaders = AnyObject;

View File

@ -16,9 +16,9 @@ import {
AxiosResponseError, AxiosResponseError,
} from './Axios'; } from './Axios';
export type AdapterRequestType = 'request' | 'download' | 'upload'; export type AxiosAdapterRequestType = 'request' | 'download' | 'upload';
export type AdapterRequestMethod = export type AxiosAdapterRequestMethod =
| 'OPTIONS' | 'OPTIONS'
| 'GET' | 'GET'
| 'HEAD' | 'HEAD'
@ -29,20 +29,20 @@ export type AdapterRequestMethod =
| 'CONNECT'; | 'CONNECT';
export interface AxiosAdapterRequestConfig extends AxiosRequestConfig { export interface AxiosAdapterRequestConfig extends AxiosRequestConfig {
type: AdapterRequestType; type: AxiosAdapterRequestType;
method: AdapterRequestMethod; method: AxiosAdapterRequestMethod;
url: string; url: string;
success(response: AxiosResponse): void; success(response: AxiosResponse): void;
fail(error: AxiosResponseError): void; fail(error: AxiosResponseError): void;
} }
export interface AxiosAdapterRequestOptions extends AxiosAdapterRequestConfig { export interface AxiosAdapterBaseOptions extends AxiosAdapterRequestConfig {
header?: AxiosRequestHeaders; header?: AxiosRequestHeaders;
success(response: any): void; success(response: any): void;
fail(error: any): void; fail(error: any): void;
} }
export interface AxiosAdapterUploadOptions extends AxiosAdapterRequestOptions { export interface AxiosAdapterUploadOptions extends AxiosAdapterBaseOptions {
filePath: string; filePath: string;
name: string; name: string;
fileName: string; fileName: string;
@ -51,14 +51,13 @@ export interface AxiosAdapterUploadOptions extends AxiosAdapterRequestOptions {
formData?: AxiosRequestData; formData?: AxiosRequestData;
} }
export interface AxiosAdapterDownloadOptions export interface AxiosAdapterDownloadOptions extends AxiosAdapterBaseOptions {
extends AxiosAdapterRequestOptions {
filePath?: string; filePath?: string;
fileName?: string; fileName?: string;
} }
export interface AxiosAdapterRequest { export interface AxiosAdapterRequest {
(config: AxiosAdapterRequestOptions): AxiosAdapterTask | void; (config: AxiosAdapterBaseOptions): AxiosAdapterTask | void;
} }
export interface AxiosAdapterUpload { export interface AxiosAdapterUpload {
@ -144,6 +143,23 @@ export function createAdapter(platform: AxiosPlatform): AxiosAdapter {
} }
} }
function transformOptions(
config: AxiosAdapterRequestConfig,
): AxiosAdapterBaseOptions {
return {
...config,
header: config.headers,
success(response: any): void {
transformResult(response);
config.success(response);
},
fail(error: any): void {
transformResult(error);
config.fail(error);
},
};
}
function injectDownloadData(response: any): void { function injectDownloadData(response: any): void {
if (!isPlainObject(response.data)) { if (!isPlainObject(response.data)) {
response.data = {}; response.data = {};
@ -165,36 +181,27 @@ export function createAdapter(platform: AxiosPlatform): AxiosAdapter {
} }
} }
function requestAdapter( function callRequest(
request: AxiosAdapterRequest, request: AxiosAdapterRequest,
config: AxiosAdapterRequestConfig, baseOptions: AxiosAdapterBaseOptions,
): AxiosAdapterTask | void { ): AxiosAdapterTask | void {
const options = Object.assign({}, config, { return request(baseOptions);
header: config.headers,
success(response: any): void {
transformResult(response);
config.success(response);
},
fail(error: any): void {
transformResult(error);
config.fail(error);
},
});
return request(options);
} }
function uploadAdapter( function callUpload(
upload: AxiosAdapterUpload, upload: AxiosAdapterUpload,
config: AxiosAdapterRequestConfig, baseOptions: AxiosAdapterBaseOptions,
): AxiosAdapterTask | void { ): AxiosAdapterTask | void {
assert(isPlainObject(config.data), '上传文件时 data 需要是一个 object');
assert( assert(
isString(config.data!.fileName), isPlainObject(baseOptions.data),
'上传文件时 data 需要是一个 object',
);
assert(
isString(baseOptions.data!.fileName),
'上传文件时 data.fileName 需要是一个 string', '上传文件时 data.fileName 需要是一个 string',
); );
assert( assert(
isString(config.data!.filePath), isString(baseOptions.data!.filePath),
'上传文件时 data.filePath 需要是一个 string', '上传文件时 data.filePath 需要是一个 string',
); );
@ -204,46 +211,33 @@ export function createAdapter(platform: AxiosPlatform): AxiosAdapter {
fileType, fileType,
hideLoading, hideLoading,
...formData ...formData
} = config.data as AxiosRequestFormData; } = baseOptions.data as AxiosRequestFormData;
const options = Object.assign({}, config, { const options = {
header: config.headers, ...baseOptions,
name: fileName, name: fileName,
fileName: fileName, fileName: fileName,
filePath, filePath,
fileType: fileType ?? 'image', fileType: fileType ?? 'image',
hideLoading, hideLoading,
formData, formData,
success(response: any): void { };
transformResult(response);
config.success(response);
},
fail(error: any): void {
transformResult(error);
config.fail(error);
},
});
return upload(options); return upload(options);
} }
function downloadAdapter( function callDownload(
download: AxiosAdapterDownload, download: AxiosAdapterDownload,
config: AxiosAdapterRequestConfig, baseOptions: AxiosAdapterBaseOptions,
): AxiosAdapterTask | void { ): AxiosAdapterTask | void {
const options = Object.assign({}, config, { const options = {
header: config.headers, ...baseOptions,
filePath: config.params?.filePath, filePath: baseOptions.params?.filePath,
fileName: config.params?.fileName, fileName: baseOptions.params?.fileName,
success(response: any): void { success(response: any): void {
injectDownloadData(response); injectDownloadData(response);
transformResult(response); baseOptions.success(response);
config.success(response);
}, },
fail(error: any): void { };
transformResult(error);
config.fail(error);
},
});
return download(options); return download(options);
} }
@ -251,13 +245,15 @@ export function createAdapter(platform: AxiosPlatform): AxiosAdapter {
return function adapterDefault( return function adapterDefault(
config: AxiosAdapterRequestConfig, config: AxiosAdapterRequestConfig,
): AxiosAdapterTask | void { ): AxiosAdapterTask | void {
const baseOptions = transformOptions(config);
switch (config.type) { switch (config.type) {
case 'request': case 'request':
return requestAdapter(platform.request, config); return callRequest(platform.request, baseOptions);
case 'upload': case 'upload':
return uploadAdapter(platform.upload, config); return callUpload(platform.upload, baseOptions);
case 'download': case 'download':
return downloadAdapter(platform.download, config); return callDownload(platform.download, baseOptions);
default: default:
throwError(`无法识别的请求类型 ${config.type}`); throwError(`无法识别的请求类型 ${config.type}`);
} }

View File

@ -1,9 +1,11 @@
import { toLowerCase } from '../helpers/utils'; import { toLowerCase } from '../helpers/utils';
import { AdapterRequestType } from './adapter'; import { AxiosAdapterRequestType } from './adapter';
import { AxiosRequestConfig, AxiosRequestMethodAlias } from './Axios'; import { AxiosRequestConfig, AxiosRequestMethodAlias } from './Axios';
export function generateType(config: AxiosRequestConfig): AdapterRequestType { export function generateType(
let requestType: AdapterRequestType = 'request'; config: AxiosRequestConfig,
): AxiosAdapterRequestType {
let requestType: AxiosAdapterRequestType = 'request';
const method = toLowerCase<AxiosRequestMethodAlias>(config.method, 'get'); const method = toLowerCase<AxiosRequestMethodAlias>(config.method, 'get');

View File

@ -2,7 +2,7 @@ import { isFunction, isPlainObject } from '../helpers/is';
import { assert, toUpperCase } from '../helpers/utils'; import { assert, toUpperCase } from '../helpers/utils';
import { import {
AxiosAdapterRequestConfig, AxiosAdapterRequestConfig,
AdapterRequestMethod, AxiosAdapterRequestMethod,
AxiosAdapterTask, AxiosAdapterTask,
} from './adapter'; } from './adapter';
import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios'; import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios';
@ -41,7 +41,7 @@ export function request<TData = any>(
...config, ...config,
url: config.url ?? '', url: config.url ?? '',
type: generateType(config), type: generateType(config),
method: toUpperCase<AdapterRequestMethod>(config.method, 'GET'), method: toUpperCase<AxiosAdapterRequestMethod>(config.method, 'GET'),
success, success,
fail, fail,
}; };