【前端续命术】请求总失败?给你的 AJAX 装上 “不死鸟” 重试 Buff

前言

精心写好的 AJAX 请求,本地测试百发百中,一到线上就间歇性 "摆烂"------ 网络抽风、服务器手抖、甚至只是宇宙射线干扰(bushi),请求就哐哐报错。

要是每次失败都直接抛给用户 "请求失败,请刷新页面" ,用户体验直接原地爆炸。这时候,给请求加个 "重试机制" 就显得尤为重要了 ------ 就像打游戏复活,失败了咱再来一次,让它失败了能自动重来。

一、先看痛点:不稳定的 AJAX 请求

先看这个模拟 AJAX 请求的代码,它模拟了网络请求的随机性:有 80% 的概率失败,20% 的概率成功,就像现实中那些不靠谱的接口一样:

JavaScript 复制代码
// 模拟不稳定的AJAX请求
function ajax() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // 生成0-9的随机数
            const random = ~~(Math.random() * 10);
            if (random < 8) {
                console.log('请求失败😭');
                reject('fail');
            } else {
                console.log('请求成功🎉');
                resolve('success');
            }
        }, 1000)
    })
}

// 普通调用:失败了就凉了
ajax()
    .then(res => console.log(res))
    .catch(err => console.log(err))

直接调用这个ajax函数,大概率会看到 "请求失败" 的提示,要是这是用户支付的关键请求,不得把用户急哭?这时候,咱们的 "重试神器" 就该登场了。

二、打造重试函数:失败了咱再来!

核心思路很简单:写一个retry函数,接收 "要执行的请求函数""重试次数",每次请求失败后,就减少一次重试次数,只要次数没耗光,就重新发起请求;直到成功,或者次数用完彻底失败。

JavaScript 复制代码
// 模拟不稳定的AJAX请求
function ajax() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const random = ~~(Math.random() * 10);
            if (random < 8) {
                console.log('请求失败😭');
                reject('fail');
            } else {
                console.log('请求成功🎉');
                resolve('success');
            }
        }, 1000)
    })
}

// 重试核心函数:给请求加"复活甲"
function retry(fn, count) {
    // 返回一个新的Promise,统一对外暴露结果
    return new Promise((resolve, reject) => {
        // 封装请求执行逻辑,方便递归调用
        const run = () => {
            fn()
                .then((res) => {
                    // 请求成功:直接resolve结果,结束流程
                    resolve(res);
                    console.log(`终于成了!结果:${res}`);
                })
                .catch((err) => {
                    // 请求失败:先减少重试次数
                    count--;
                    console.log(`还剩${count}次重试机会`);
                    // 还有重试次数:递归调用run,再来一次
                    if (count) {
                        console.log('准备重试...');
                        run();
                    } else {
                        // 次数用完:彻底失败,reject结果
                        reject('重试次数耗尽,请求彻底失败💥');
                    }
                })
        }
        // 首次执行请求
        run();
    })
}

// 调用重试函数:最多重试 3次
retry(ajax, 3)
    .then(res => console.log(`最终结果:${res}`))
    .catch(err => console.log(`最终结果:${err}`));

就算前两次都失败,第三次成功了,整个流程就会返回成功;如果 3 次都失败,就会输出:

关键逻辑拆解:

  • 外层 Promiseretry函数返回新 Promise,不管内部重试多少次,对外只暴露最终的成功 / 失败结果,符合 Promise 的链式调用习惯
  • run 函数递归 :把请求逻辑封装在run里,失败后只要还有重试次数,就递归调用run,实现 "自动重试"
  • 次数控制 :每次失败count--,当count为 0 时,不再重试,直接reject,避免无限循环

三、进阶小技巧:让重试更 "聪明"

当然,实际开发中咱们的重试机制可以更完善,比如:

  • 添加延迟重试:失败后不要立刻重试,等几百毫秒再试(避免高频请求压垮服务器)
  • 指数退避:重试间隔越来越长(比如 1s→2s→4s),更符合网络请求的最佳实践
  • 自定义失败条件:不是所有失败都重试(比如 404 是资源不存在,重试也没用)

举个加延迟的小改造:

JavaScript 复制代码
function retry(fn, count, delay = 1000) {
    return new Promise((resolve, reject) => {
        const run = () => {
            fn()
                .then(res => {
                    resolve(res);
                    console.log(`终于成了!结果:${res}`);
                })
                .catch(err => {
                    count--;
                    console.log(`还剩${count}次重试机会`);
                    if (count) {
                        console.log(`等待${delay}ms后重试...`);
                        // 延迟重试
                        setTimeout(run, delay);
                    } else {
                        reject('重试次数耗尽,请求彻底失败💥');
                    }
                })
        }
        run();
    })
}

结语

写代码就像过日子,哪能事事一帆风顺? 修复 bug 也是人生中繁琐的乐趣。

相关推荐
小小小小宇2 分钟前
设计稿转代码:如何将生成代码与内部组件库关联
前端
七牛云行业应用3 分钟前
别每个 AI 工具单独配了!MCP 一次搭建,Claude、Cursor、TRAE 全能用
前端
_xaboy3 分钟前
FormCreate 设计器 v6.3 正式发布:AI 表单助理3.0登场!
前端·vue.js·低代码·开源·表单设计器
胡志辉4 分钟前
邮件中点击“加载图片”,你的IP地址已经被泄漏
前端·后端·安全
openKaka_16 分钟前
reconcileChildren 深入:React 如何根据 ReactElement 构建子 Fiber
前端·javascript·react.js
三翼鸟数字化技术团队31 分钟前
事件循环原来这么简单!
前端
gf132111132 分钟前
python_【更新已发送的消息卡片】
java·前端·python
zithern_juejin39 分钟前
typeof、instanceof与Object.prototype.toString()
javascript
一点一木42 分钟前
2026 终端 AI 编码 Agent 六大工具深度横评
前端·人工智能·claude
Highcharts.js1 小时前
Highcharts React v5升级三问|最大的升级方向是什么?需要注意什么?有什么优化?
前端·javascript·react.js·前端框架·highcharts·大数据渲染·前端性能