前言
在前端的日常开发中,取消请求是经常会用到的一个功能,比如跳转新页面,取消前一个页面还未返回的请求,tab 切换时,取消上一个 tab 页还未返回的请求等。本文着重介绍前端常用的HTTP库Axios是如何实现请求的取消的。
使用方法
Axios是通过cancel token API来实现取消请求的,具体的使用方法有两种:
- 使用
CancelToken.source工厂方法创建cancel token - 传递一个
excutor函数到CancelToken的构造函数来创建cancel token
1 使用CancelToken.source工厂方法创建cancel token
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceld', thrown.message)
} else {
// 处理错误
}
}
// 取消请求(message参数是可选的)
source.cancel('Operation canceld by the user.')
2 传递一个excutor函数到CancelToken的构造函数来创建cancel token
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function excutor(c) {
// excutor函数接受一个cancel函数作为参数
cancel = c
})
})
// cancel the request
cancel()
以上使用方法参考自:axios中文文档
实现原理
我们知道,原生的XMLHttpRequest是支持取消 http 请求的,通过XMLHttpRequest.abort() API
,其实Axios实现对请求的取消,最终也是通过XMLHttpRequest.abort(),只不过是使用了Promise进行了封装。
我们来看一下源码:
以上是
CancelToken源码,可以看到,当我们通过传递一个excutor函数到CancelToken的构造函数的方式来创建cancel token时,通过CancelToken构造函数创建一个cancelToken实例,全局变量cancel取到了excutor函数的参数函数,当外部执行cancel函数时,excutor参数函数里面的代码就会执行,执行体里面执行了cancelToken实例的promise的resolve方法,这就意味着,如果该promise有定义then方法,那么then方法就要执行了。
接下来:
代码中通过判断用户是否配置了
cancelToken属性,如果配置了,就给该配置的cancelToken实例定义then方法,而then方法里面做的就是调用XMLHttpRequest.abort()方法取消请求。
使用CancelToken.source工厂方法创建cancelToken原理也是一样的,只是提供另一种api调用形式: