失败重试的函数实现
七崽爱吃小饼干2026/03/02阅读 1
实现 retry 函数(循环 + 递归双版本)
题目要求
实现一个 retry 函数:
- 入参:一个异步函数
fn、最大重试次数times - 返回:一个新的异步函数
- 功能:执行失败后自动重试,最多重试
times次 - 核心规则:必须在上一次失败后,才发起下一次重试(串行执行)
核心通用逻辑
- 包装原异步函数,返回新函数,保持调用方式一致
- 失败后重试,成功直接返回结果
- 耗尽重试次数仍失败,抛出最终错误
- 串行执行:上一次结束 → 再执行下一次
写法一:for 循环实现(最稳妥、无栈溢出风险)
javascript
function retry(fn, times) {
return async (...args) => {
// 总共执行:首次 1 次 + 重试 times 次
for (let i = 0; i <= times; i++) {
try {
// 等待执行完成(成功/失败)
return await fn(...args);
} catch (err) {
// 最后一次仍失败:抛出错误
if (i === times) throw err;
// 否则继续循环重试
}
}
};
}
优点
- 逻辑直观、好理解
- 无递归深度限制,绝对安全
- 面试官无任何可挑剔点
写法二:递归实现(更简洁、语义更贴合重试)
javascript
function retry(fn, times) {
return async (...args) => {
const execute = async (remainTimes) => {
try {
return await fn(...args);
} catch (err) {
// 无剩余次数:抛出错误
if (remainTimes <= 0) throw err;
// 失败后递归重试,次数-1
return execute(remainTimes - 1);
}
};
// 首次执行,传入最大重试次数
return execute(times);
};
}
优点
- 重试 = 失败后重新执行自身,语义完美匹配递归
- 代码更精简优雅
- 常规重试次数(3~5次)绝对不会栈溢出
两种写法对比总结
| 写法 | 实现思路 | 优点 | 适用场景 |
|---|---|---|---|
| 循环 | 用 for 循环控制执行次数 | 安全无风险、易懂 | 所有场景,稳妥首选 |
| 递归 | 失败后调用自身重试 | 简洁、语义优雅 | 常规次数,优雅首选 |