一、 axios重新发送请求基础版(所有的请求错误,不论是请求超时还是接口请求出错都会进行重试)

以下是一个完整的文件,看懂了的话axios重试请求也就基本会了,不会的话直接复制到项目里,也可以直接调用使用。

1. 创建一个axios实例,并在实例中设置请求超时时间timeout、重试请求次数retry、请求间隔retryDelay。

2. 为实例设置相应拦截器,在请求返回错误的时候对错误做处理。

3. 如果请求次数已经达到设置好的请求次数,不再发送请求,返回最终的错误信息;

    如果请求次数还没有达到设置好的请求次数,就在停留retryDelay(请求间隔)时间后,再次发起请求

import axios from 'axios';
//创建一个axios实例
const requests = axios.create({
  timeout: 5 * 1000, //请求超时时间(5秒后还未接收到数据,就需要再次发送请求)
  retry: 3, //设置全局重试请求次数(最多重试几次请求)
  retryDelay: 1000, //设置全局请求间隔
});

//响应拦截器
requests.interceptors.response.use((res) => {
  return Promise.resolve(res.data);
}, (error) => {
  //console.log(error);
  //超时处理 error.config是一个对象,包含上方create中设置的三个参数
  var config = error.config;
  if (!config || !config.retry) return Promise.reject(error);

  // __retryCount用来记录当前是第几次发送请求
  config.__retryCount = config.__retryCount || 0;

  // 如果当前发送的请求大于等于设置好的请求次数时,不再发送请求,返回最终的错误信息
  if (config.__retryCount >= config.retry) {
    return Promise.reject(error);
  }

  // 记录请求次数+1
  config.__retryCount += 1;

  // 设置请求间隔 在发送下一次请求之前停留一段时间,时间为上方设置好的请求间隔时间
  var backoff = new Promise(function (resolve) {
    setTimeout(function () {
      resolve();
    }, config.retryDelay || 1);
  });

  // 再次发送请求
  return backoff.then(function () {
    return requests(config);
  });
})

export default requests;
  • error.config:

  • 请求次数:

可以看到控制台的error输出了4次,但是retry明明设置的是3,怎么会有4次输出呢?这是因为retry设置的是最多重试几次请求,它设置的是重试次数,而第一次输出是第一次发送请求返回输出,后三次才是重试请求的输出。

二、 axios重新发送请求升级版(能够识别出网络错误,但接口报错也会在达到请求次数后才返回)

在 if (config.__retryCount >= config.retry) {} 中增加对网络错误的识别,reject中的内容可以自定义,这里的reject中写了什么,发送异步请求后的错误捕捉catch中的error就是什么。

// 如果当前发送的请求大于等于设置好的请求次数时,不再发送请求,返回最终的错误信息
  if (config.__retryCount >= config.retry) {
    if (error.message === "Network Error") {
      //message为"Network Error"代表断网了
      return Promise.reject({type: "warning",msg: "网络连接已断开,请检查网络"});
    } else if (error.message === "timeout of 5000ms exceeded") {
      //网太慢了,5秒内没有接收到数据,这里的5000ms对应上方timeout设置的值
      return Promise.reject({type: "warning",msg: "请求超时,请检查网络"});
    } else {
      //除以上两种以外的所有错误,包括接口报错 400 500 之类的
      return Promise.reject({type: "error",msg: "出现错误,请稍后再试"});
    }
  }
  • error.message:

三、 axios重新发送请求高级版(非网络错误不重试请求,直接返回错误信息)

    网络连接出错我们可以尝试多次请求,说不定哪一次网络就通了,但是如果是类似于接口的路径写错啦,404、500之类的错误,我们其实不需要多次请求,因为再多少次的请求他们的结果也不会改变。

    所以这个时候我们就需要拦截这样的错误,直接返回错误信息,不再重新发送请求。

    可以根据error.response.data是否有值来判断接口有没有返回响应,data结果为undefined的时候很明显就是发送了请求但是没接收到结果,可能是网络问题;data有值也就是有返回结果, 我们可以根据返回结果来自定义处理内容。

    在 if (!config || !config.retry) return Promise.reject(error); 的下方增加判断。

if (!config || !config.retry) return Promise.reject(error);

//如果有响应内容,就直接返回错误信息,不再发送请求
if(error.response.data){
  return Promise.reject({type: "error", msg: error.response.data});
}
  •  接口路径写错后的报错:(举个栗子,404接口找不到的error长这样)

 

四、 总体代码

import axios from 'axios';
//创建一个axios实例
const requests = axios.create({
  timeout: 5 * 1000, //请求超时时间(5秒后还未接收到数据,就需要再次发送请求)
  retry: 3, //设置全局重试请求次数(最多重试几次请求)
  retryDelay: 1000, //设置全局请求间隔
});

//响应拦截器  
requests.interceptors.response.use((res) => {
  return Promise.resolve(res.data);
}, (error) => {
  //console.log(error);
  //超时处理 error.config是一个对象,包含上方create中设置的三个参数
  var config = error.config;
  if (!config || !config.retry) return Promise.reject(error);

  //如果有响应内容,就直接返回错误信息,不再发送请求
  if(error.response.data){
    return Promise.reject({type: "error", msg: error.response.data});
  }

  // __retryCount用来记录当前是第几次发送请求
  config.__retryCount = config.__retryCount || 0;

  // 如果当前发送的请求大于等于设置好的请求次数时,不再发送请求,返回最终的错误信息
  if (config.__retryCount >= config.retry) {
    if (error.message === "Network Error") {
      //message为"Network Error"代表断网了
      return Promise.reject({type: "warning",msg: "网络连接已断开,请检查网络"});
    } else if (error.message === "timeout of 5000ms exceeded") {
      //网太慢了,5秒内没有接收到数据,这里的5000ms对应上方timeout设置的值
      return Promise.reject({type: "warning",msg: "请求超时,请检查网络"});
    } else {
      //除以上两种以外的所有错误,包括接口报错 400 500 之类的
      return Promise.reject({type: "error",msg: "出现错误,请稍后再试"});
    }
  }
  
  // 记录请求次数+1
  config.__retryCount += 1;

  // 设置请求间隔 在发送下一次请求之前停留一段时间,时间为上方设置好的请求间隔时间
  var backoff = new Promise(function (resolve) {
    setTimeout(function () {
      resolve();
    }, config.retryDelay || 1);
  });

  // 再次发送请求
  return backoff.then(function () {
    return requests(config);
  });
})

export default requests;

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐