接口定义
export interface Cancel {
message?: string
}
export interface CancelStatic {
new(message?: string): Cancel
}
export interface AxiosStatic extends AxiosInstance {
create(config?: AxiosRequestConfig): AxiosInstance
CancelToekn: CancelTokenStatic
Cancel: CancelStatic
isCancel: (value: any) => boolean
}
其中 Cancel
是实例类型的接口定义,CancelStatic
是类类型的接口定义,并且我们给 axios
扩展了多个静态方法。
代码实现
我在 cancel
目录下创建 Cancel.ts
文件。
export default class Cancel {
message?: string
constructor(message?: string) {
this.message = message;
}
}
export function isCancel(value: any): boolean {
return value instanceof Cancel;
}
src/CancelToken.ts
import { Canceler, CancelExecutor, CancelTokenSource } from '../types'
import Cancel from './Cancel';
interface ResolvePromise {
(reason?: Cancel): void
}
export default class CancelToken {
promise: Promise<Cancel>
reason?: Cancel
constructor(executor: CancelExecutor) {
let resolvePromise: ResolvePromise
this.promise = new Promise<Cancel>(resolve => {
// 将 pending 的 resolve 复制给 resolvePromise
resolvePromise = resolve;
})
executor(message => {
if (this.reason) {
return
}
this.reason = new Cancel(message);
resolvePromise(this.reason);
})
}
static source(): CancelTokenSource {
let cancel!: Canceler;
const token = new CancelToken(c => {
cancel = c;
});
return {
cancel,
token
}
}
}
src/axios.ts
import { AxiosRequestConfig, AxiosStatic } from './types'
import Axios from './core/Axios'
import { extend } from './helpers/utils'
import defaults from './defaults';
import mergeConfig from './core/mergeConfig'
import CancelToken from './cancel/CancelToken';
import Cancel, { isCancel } from './cancel/Cancel';
function createInstance(config: AxiosRequestConfig): AxiosStatic {
const context = new Axios(config);
const instance = Axios.prototype.request.bind(context);
extend(instance, context);
return instance as AxiosStatic;
}
const axios = createInstance(defaults);
// axios.create 方法实现
axios.create = function create(config) {
return createInstance(mergeConfig(defaults, config));
}
axios.CancelToken = CancelToken;
axios.Cancel = Cancel;
axios.isCancel = isCancel;
export default axios;