axios取消多次重复请求和超时重传机制

1,485 阅读1分钟

取消多次重复请求

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);
    });
})