chaihongjun.me

使用axios-retry库让axios请求出现错误后自动重试

首先是安装

npm install axios-retry

然后是具体配置:

// 创建 axios 实例
const service = axios.create({
  baseURL: import.meta.env.DEV ? '/api' : 'https://maoyan.chaihongjun.me/api',
  timeout: 10000, // 请求超时时间

})

// 配置重试,第一个参数是axios的实例,第二个参数是配置对象
axiosRetry(service, {
  retries: 3, //重试次数
  retryDelay: (retryCount) => {
    return retryCount * 3000 // 每次重试间隔递增
  },
  shouldResetTimeout: true,       //  重置超时时间
  retryCondition: (error) => {
    //true为打开自动发送请求,false为关闭自动发送请求
    // 当错误信息包含timeout 超时,或者任意错误的状态码,都会自动重试
    if (error.message.includes('timeout') || error.message.includes("status code")) {
      return true;
    } else {
      return false;
    };
  },
})

以上重试可能有问题,当服务器返回404,或者403,429等状态码的时候尝试重试是没有意义的。另外retryDelay的配置(retryCount从0开始计数)是当第一次请求失败之后,0,3,6秒开始重试请求,不够合理所以,配置再优化一下:

// 创建 axios 实例
const service = axios.create({
  baseURL: import.meta.env.DEV ? '/api' : 'https://maoyan.chaihongjun.me/api',
  timeout: 10000, // 请求超时时间

})

// 配置重试,第一个参数是axios的实例,第二个参数是配置对象
axiosRetry(service, {
  retries: 3, //重试3次
  retryDelay: (retryCount) => (retryCount + 1) * 2000, // 延迟 2s/4s/6s
  shouldResetTimeout: true, //axios每次请求可以用的时间 都是timeout
  retryCondition: (error) => {
    // 1. 超时或网络断开
    if (error.code === 'ECONNABORTED' || !error.response) return true;
    // 2. 仅重试服务器错误 (5xx)
    return error.response.status >= 500;
  }
});

retryDelay用来定义重试的延迟时间,retryCount则从0开始计数。因retries设置为了3,所以retryCount可能的值是0,1,2。根据retryDelay方法可以设置对应每次延迟多久之后重试发送请求。重试的条件配置为网络断开超时,或者是服务器端的错误(5XX状态码),避免客户端错误而没有意义的重复请求。

以上整个配置的意思:当axios发送请求,给请求可用的时间是timeout配置的时间,这时间内出现超时或者网络断开了或者是服务器返回状态码5开头了,这任意情况之一,那么axios即将自动重试,第一次的重试时间是(0+1)*2000 ,也就当发现请求错误之后的2秒开始发送第一次重试,因为shouldResetTimeout:true,第一次以及后续的全部重试都给出请求可以用的时间都是timeout配置的5秒。当第一次重试5秒内,依然是没有返回正确的结果引起第二次重试,那么第二次重试的开始的时间是,第一次重试失败之后的(1+1)*2000,4秒之后。如果有第三次重试,那么第三次的重试是第二个重试失败之后的(2+1)*2000,6秒之后。每次重试给到请求的时间都是5秒。

知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:柴宏俊»