失败重试是 对可能失败的操作进行自动重复尝试的容错机制。比如前端支付场景,如果首次请求超时,可以尝试重试 2-3 次。可以通过递归调用实现,核心是错误捕获和次数控制。
我们用test
函数模拟了一个高失败率的异步请求,通过 setTimeout
模拟 500ms 网络延迟,生成 0-9 的随机数,若 <8
返回失败,否则成功。
javascript
function test() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const time = Math.floor(Math.random() * 10)
console.log(time)
if (time < 8) {
reject('失败')
} else {
resolve('成功')
}
}, 500)
})
}
当我们面对一个失败率高的异步操作时(如示例中成功率仅20%的test
函数),手动重复调用显然不够优雅。现在我们希望打造一个retry
函数,它接受一个函数fn
和一个最大重试次数maxTimes
。这个函数的核心使命是:对可能失败的操作进行自动重复尝试,在失败时自动发起有限次数的重试,直到成功或达到最大次数。
让我们观察这个retry
函数的实现:
scss
function retry(fn, maxTimes = 3) {
let count = 1
return new Promise((resolve, reject) => {
const repeat = () => {
fn()
.then((res) => {
resolve(res)
})
.catch((err) => {
count++
if (count > maxTimes) {
reject(err)
} else {
repeat()
}
})
}
repeat()
})
}
retry
函数通过计数器 count
追踪当前重试次数。首次调用 retry(test, 3)
时,立即触发 repeat
函数发起首次请求。此时 test
函数被调用
- 成功场景 :
.then
捕获结果并直接返回,终止重试流程。 - 失败场景 :
.catch
将计数器递增,若超过最大重试次数,则抛出最终错误;否则立即递归调用repeat
发起下一次请求。
总结:
通过实现 retry
函数,我们能够在异步操作失败时自动重试。这种失败重式机制在实际开发中非常有用,特别是在处理网络请求、数据库操作等可能由于临时网络问题或其他原因而失败的场景。
retry
函数通过 闭包管理重试次数 与 递归调用 实现了对异步操作的自动重试机制,核心逻辑如下:
- 控制次数
使用count
变量记录当前尝试次数,确保每次失败后递增并校验是否超过maxTimes
,避免无限重试。 - 递归发起请求
通过repeat
函数递归调用自身,在失败时触发下一次尝试。借助 Promise 的链式调用,将异步操作串联,直至成功或达到最大次数。