axios官网文档上取消请求的两种方式
使用CancelToken.source工厂创建一个取消令牌:
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
//取消请求(消息参数是可选的)
source.cancel('操作被用户取消。');
还可以通过将执行器函数传递给CancelToken构造函数来创建取消令牌:
var CancelToken = axios.CancelToken;
var cancel;
axios.get('/ user / 12345',{
cancelToken:new CancelToken(function executor(c){
//一个执行器函数接收一个取消函数作为参数
cancel = c;
})
});
// 取消请求
clear();
根据文档上的第二种方法,我们可以在拦截器里统一处理取消重复请求
let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let cancelToken = axios.CancelToken;
let removePending = (config) => {
for(let p in pending){
if(pending[p].u === config.url + '&' + config.method) { //当当前请求在数组中存在时执行函数体
pending[p].f(); //执行取消操作
pending.splice(p, 1); //把这条记录从数组中移除
}
}
}
//添加请求拦截器
axios.interceptors.request.use(config=>{
removePending(config); //在一个ajax发送前执行一下取消操作
config.cancelToken = new cancelToken((c)=>{
// 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
pending.push({ u: config.url + '&' + config.method, f: c });
});
return config;
},error => {
return Promise.reject(error);
});
//添加响应拦截器
axios.interceptors.response.use(response=>{
removePending(res.config); //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
return response;
},error =>{
return { data: { } }; 返回一个空对象,主要是防止控制台报错
});
效果
同一个请求,没有完成的请求将被取消
未完成的ajax被取消
结论
利用这个方法,一方面可以防止重复点击不同页码导致的表格数据闪烁,另外可以做实时搜索,始终获取最新结果。
网友评论
let pending = []
let CancelToken = axios.CancelToken
let removePending = (config, f) => {
let flagUrl = config.url + '&' + config.method
if (pending.indexOf(flagUrl) !== -1) {
if (f) {
f() // 执行取消操作
} else {
pending.splice(pending.indexOf(flagUrl), 1)// 把这条记录从数组中移除
}
} else {
if (f) {
pending.push(flagUrl)
}
}
}
// http request 拦截器
HTTP.interceptors.request.use(
config => {
if (config.method === 'post') {
console.log('我是拦截')
config.cancelToken = new CancelToken((c) => {
removePending(config, c)
})
}
return config
},
err => {
return Promise.reject(err)
})
// http response 拦截器
HTTP.interceptors.response.use(
response => {
if (response.config.method === 'post') {
removePending(response.config)
}
return response
},
error => {
pending = []
return { data: {error: error} } // 返回接口返回的错误信息
})