[axios] Cancel 类实现及 axios 的扩展

2022-06-23  本文已影响0人  小黄人get徐先生

接口定义

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;
上一篇下一篇

猜你喜欢

热点阅读