实现一个支持请求失败后重试的JS方法

本文介绍如何使用Promise和递归来封装一个支持多次重试的async函数,以应对网络请求可能的失败。通过实例展示了如何在遇到错误时自动进行有限次重试,提高代码健壮性。

假设存在一个函数,返回promise对象。它可能会失败。

// 伪代码
function asyncFunc(){
    return new Promise((resolve,reject)=>{
        axios.get('http://sdadasdadadasdas.com').then((res)=>{
            resolve(res)
        }).catch((err)=>{
           reject(err)
        })
    })
}

包装上面的函数支持重试。

// 支持重试的函数
function reTry(asyncFunc,times) {    //times是重试次数
    return new Promise(async (resolve, reject) => {
        function reTryFunc(times) {
            console.log(`第${times}次重试`)
            asyncFunc().then((res) => {
                    resolve(res)
            }).catch((err) => {
                if (times > 0) {
                    console.log(`----第${times}次重试`)
                    setTimeout(() => {
                        reTryFunc(times - 1)
                    })
                } else {
                    reject(err)
                }
            })
        }
        reTryFunc(times)
    })
}

### 实现请求失败后的自动重试机制 在前端开发中,为了提高网络请求的可靠性和用户体验,通常需要实现请求失败后的自动重试机制。这种机制可以在遇到短暂的网络波动或接口异常时,自动尝试重新发送请求,从而减少用户感知的失败风险。 #### 1. 使用递归方法实现请求重试 可以通过封装一个通用的 `retry` 函数来实现请求的多次尝试。该函数接收请求函数、参数和最大重试次数作为输入,并在请求失败后递归调用自身,直到达到最大重试次数为止: ```javascript function retry(fn, params, maxRetries) { let retries = 0; function attempt() { return fn(params).catch(err => { if (retries < maxRetries) { retries++; return attempt(); } else { return Promise.reject(err); } }); } return attempt(); } ``` 通过这种方式,可以确保请求失败后自动重试,同时避免无限循环[^1]。 #### 2. 使用 Axios 和 axios-retry 插件实现自动重试 Axios 是一个广泛使用的 HTTP 客户端库,支持异步请求。结合 `axios-retry` 插件,可以轻松实现请求失败后的自动重试功能。具体步骤如下: - **安装依赖** ```bash npm install axios axios-retry ``` - **配置 Axios 实例并启用重试功能** ```javascript import axios from 'axios'; import axiosRetry from 'axios-retry'; const service = axios.create({ baseURL: "http://127.0.0.1:7002", timeout: 20 * 1000, }); axiosRetry(service, { retries: 3, retryDelay: (retryCount) => { return retryCount * 1000; }, shouldResetTimeout: true, retryCondition: (error) => { console.log("error", error.message); return true; }, onRetry: function (retryCount) { console.log('err', retryCount); }, }); ``` - **执行请求** ```javascript let s = await service.get('/test'); ``` 上述代码展示了如何使用 `axios-retry` 插件实现请求失败后的自动重试。其中 `retries` 设置了最大重试次数,`retryDelay` 控制每次重试之间的延迟时间,`retryCondition` 可以根据错误类型决定是否需要重试,而 `onRetry` 则用于记录重试次数[^2]。 #### 3. 结合去重机制防止重复请求 为了避免在同一时间内多次发送相同的请求,可以在请求拦截器中加入去重逻辑。具体做法是为每个请求生成唯一的标识符,并通过集合管理这些标识符,从而防止重复请求的发生: ```javascript const pendingRequests = new Set(); function generateRequestKey(config) { const { method, url, params, data } = config; return `${method}&${url}&${JSON.stringify(params)}&${JSON.stringify(data)}`; } axios.interceptors.request.use(config => { const reqKey = generateRequestKey(config); if (pendingRequests.has(reqKey)) { return Promise.reject(new Error('Duplicate request')); } pendingRequests.add(reqKey); config.reqKey = reqKey; return config; }); axios.interceptors.response.use( response => { pendingRequests.delete(response.config.reqKey); return response; }, error => { pendingRequests.delete(error.config?.reqKey); return Promise.reject(error); } ); ``` 通过引入去重机制,可以有效避免因请求失败后自动重试而导致的重复请求问题,从而提升系统的稳定性和性能[^3]。 #### 4. 综合策略 为了更好地应对请求失败后重复发送请求的问题,建议采取以下综合策略: - **设置合理的重试次数**:根据业务需求设定最大重试次数,避免无限循环。 - **引入去重机制**:在请求拦截器中生成唯一的请求标识符,并通过集合管理这些标识符以防止重复请求。 - **添加延迟重试**:在每次重试之间加入适当的延迟,减少服务器压力。 - **记录日志**:对于失败请求进行详细记录,便于后续分析和优化。 通过以上方法,可以有效解决前端请求失败后重复发送请求的问题,提高系统的稳定性和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值