返回

Axios源码剖析及CancelToken类封装详解

前端

如今,Axios已成为前端开发中最受欢迎的请求库之一,它不仅适用于浏览器端,在服务端同样适用,为开发者提供了更丰富的功能和更便捷的开发体验。

为了更深入地了解Axios,我们接下来将对它的源码进行详细解析。同时,为了让大家能够更好地掌握前端开发技巧,我们还将封装一个CancelToken类,帮助你轻松取消请求。

Axios源码解析

为了更好地了解Axios的工作原理,我们首先需要解析它的源码。

// axios.js
import { AxiosPromise, AxiosRequestConfig } from './types'
import { parseHeaders } from './helpers/headers'
import { createError } from './helpers/error'

export default function axios(config: AxiosRequestConfig): AxiosPromise {
  ...
}

上段代码是Axios的入口函数,它接受一个AxiosRequestConfig类型的配置对象作为参数,并返回一个AxiosPromise类型的Promise对象。

接下来,我们来看一下Axios是如何发送请求的。

// axios.js
export default function axios(config: AxiosRequestConfig): AxiosPromise {
  ...
  // 创建一个XMLHttpRequest对象
  const request = new XMLHttpRequest()

  // 设置请求头
  setRequestHeader(request, config.headers)

  // 监听请求状态变化
  request.onreadystatechange = function() {
    ...
  }

  // 发送请求
  request.send(data)

  ...
}

在上述代码中,首先创建一个XMLHttpRequest对象,然后设置请求头,再监听请求状态变化,最后发送请求。

CancelToken类封装

CancelToken类是一个帮助我们取消请求的类,它可以用来控制请求的发送和取消。

// cancelToken.js
export class CancelToken {
  constructor(executor) {
    ...
  }

  cancel() {
    ...
  }
}

上段代码定义了一个CancelToken类,它的构造函数接收一个executor函数作为参数,该函数接收两个参数:resolve和reject。

// cancelToken.js
export class CancelToken {
  constructor(executor) {
    // 创建一个Promise对象
    const promise = new Promise((resolve, reject) => {
      executor(resolve, reject)
    })

    // 将Promise对象保存起来
    this.promise = promise
  }

  cancel() {
    ...
  }
}

在上述代码中,首先创建一个Promise对象,然后将它保存起来。

// cancelToken.js
export class CancelToken {
  constructor(executor) {
    ...
  }

  cancel() {
    // 调用Promise对象的reject方法
    this.promise.reject(new Cancel())
  }
}

在上述代码中,当调用CancelToken类的cancel方法时,会调用Promise对象的reject方法,并传入一个Cancel对象作为参数。

// cancelToken.js
export class CancelToken {
  constructor(executor) {
    ...
  }

  cancel() {
    ...
  }

  throwIfRequested() {
    ...
  }
}

在上述代码中,当调用CancelToken类的throwIfRequested方法时,会检查Promise对象的state属性,如果state属性为“rejected”,则抛出Cancel对象作为异常。

使用方法

// 使用CancelToken类取消请求
const cancelToken = new CancelToken((resolve, reject) => {
  setTimeout(() => {
    reject(new Cancel())
  }, 1000)
})

axios.get('/api/data', {
  cancelToken: cancelToken
}).then((response) => {
  ...
}).catch((error) => {
  if (axios.isCancel(error)) {
    console.log('请求已取消')
  } else {
    console.log('请求出错')
  }
})

上段代码演示了如何使用CancelToken类取消请求。首先创建一个CancelToken对象,然后将其传递给axios.get方法的cancelToken属性。当CancelToken对象的cancel方法被调用时,请求就会被取消。