原文链接
通过axios.CancelToken.source
生成取消令牌token
和取消方法cancel
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
通过axios.CancelToken
构造函数生成取消函数
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// An executor function receives a cancel function as a parameter
cancel = c;
})
});
// cancel the request
cancel();
需要注意的是在
catch
中捕获异常时,应该使用axios.isCancel()
判断当前请求是否是主动取消的,以此来区分普通的异常逻辑。
#创建map 存储 键值对
#分装存储请求方法
#分装取消请求方法
#调用
const pending = new Map() // 声明一个 Map 用于存储每个请求的标识 和 取消函数
const changePending = (config) => {
const url = [
config.method, //方法
config.url,//路径
qs.stringify(config.params),//查询参数
qs.stringify(config.data)//提交数据
].join('&') //转换成字符串
config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
if (!pending.has(url)) {
// 如果 pending 中不存在当前请求,则添加进去
pending.set(url, cancel) //键:url 值:取消函数
}else if(pending.has(url)) {
// 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除
let cancel = pending.get(url)
cancel(url)
pending.delete(url)
}
})
}
axios.interceptors.request.use(config => {
changePending(config)
return config
},error => {
return Promise.reject(error)
})
axios.interceptors.response.use(config => {
changePending(config)
},error => {
//需要注意的是在`catch`中捕获异常时,应该使用`axios.isCancel()`判断当前请求是否是主动取消的,
if(axios.isCancel(error)){
console.log('repeated request: ' + error.message)
}
return Promise.reject(error)
})
/**
* 清空 pending 中的请求(在路由跳转时调用)
*/
export const clearPending = () => {
for (const [url, cancel] of pending) {
cancel(url)
}
pending.clear()
}
#将clearPending()方法添加到vue路由钩子函数中
router.beforeEach((to, from, next) => {
clearPending()
// ...
next()
})