取消多次重复请求
const ins = axios.create({...});
let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let cancelToken = axios.CancelToken;
let removeRepeatUrl = (ever) => {
for(let p in pending){
let arg = ever.method === 'get' ? JSON.stringify(ever.params) : JSON.stringify(ever.data)
if(pending[p].u === ever.url + '&' + ever.method + arg) { // 当前请求在数组中存在时执行函数体
pending[p].f(); //执行取消操作
pending.splice(p, 1); //把这条记录从数组中移除
}
}
}
// 请求拦截器
axios.interceptors.request.use(config => {
//在一个ajax发送前执行一下取消操作
removeRepeatUrl(config);
config.cancelToken = new cancelToken((c)=>{
let arg = config.method === 'get' ? JSON.stringify(config.params) : JSON.stringify(config.data)
// 自定义唯一标识
pending.push({ u: config.url + '&' + config.method + arg, f: c });
});
return config
}, err => {
return Promise.reject(err)
})
// 响应拦截器
axios.interceptors.response.use(res => {
removeRepeatUrl(res.config); //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
const data = res.data
return data
}, err => {
return Promise.reject(err)
})
超时重传机制
直接将retry等属性直接放在config上,可能被axios过滤掉了,现在放在config.headers中
// 设置请求超时时间的毫秒数
axios.defaults.timeout = 10000
// 设置全局请求次数,和再次请求等待毫秒数
axios.defaults.headers.retry = 3
axios.defaults.headers._retryCount = 0
axios.defaults.headers.retryDelay = 1000
// 响应拦截器
axios.interceptors.response.use(res => {
// ...
}, err => {
let config = err.config;
// 重复次数为0表示取消重传
if (config && !config.headers.retry) {
return Promise.reject(err);
}
config.headers.__retryCount = config.headers.__retryCount || 0;
if (config.headers.__retryCount >= config.headers.retry) {
return Promise.reject(err);
}
config.headers.__retryCount += 1;
// 增加超时时间
config.timeout = config.timeout + config.headers.__retryCount * 3000;
var backoff = new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, config.headers.retryDelay || 1000);
});
return backoff.then(function() {
return axios(config);
});
})