Axios源码剖析及CancelToken类封装详解
2024-01-31 07:30:09
如今,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方法被调用时,请求就会被取消。