关于Axios请求错误或超时的重连机制

在VUE项目的研发中,我们经常会使用axios发起网络请求。在服务器或者网络不稳定的情况下,常常会选择直接抛出错误。但为了交互的友好性,我们有必要配置出现网络不佳或请求失败的重连机制。

过多的原理就不多阐述,相信大家已经查阅了不少文章去了解和认识了。下面我们直接通过实战代码来一起学习:


import axios from 'axios'
// 格式化表单数据的插件
import qs from 'qs'

// axios 初始化
const request = axios.create({
    // ...
    retry: 1,     // 自定义重连次数
    // ...
});

// ...

/**
 * 响应拦截器
 */
request.interceptors.response.use(
    /**
     * 成功返回数据
     * @param response
     * @returns {any | {}}
     */
    response => {
        return response.data || {}
    },
    /**
     * 处理请求错误
     * @param err
     * @returns {Promise<never>|Promise<AxiosResponse<any> | any>}
     */
    err => {
        // 重发流程
        let config = err.config
        // 检测是否配置重发参数
        if(!config || !config.retry) return Promise.reject(err)

        // 获取/初始化追踪重试次数的变量
        config.__retryCount = config.__retryCount || 0

        // 检查是否已经达到重试总数
        if(config.__retryCount >= config.retry)  return Promise.reject(err)

        // ----------------- 重连逻辑 -----------------

        // 重试次数 + 1
        config.__retryCount += 1

        // 自动计算每次重试的延时,重试次数越多,延时越大
        let delay = ((1/2) * (Math.pow(2, config.__retryCount) - 1)) * 1000;

        // 创建新的 Promise 来发起请求
        let backoff = new Promise((resolve) => {
            setTimeout(() => {
                resolve()
            }, delay)
        })

        // 返回新的 axios 请求结果
        return backoff.then(function(err) {
            // 设置并格式化传输的数据
            config.data = qs.parse(config.data)
            return request(config)
        })
    }
)

export default request;