如何实现一个带重试机制的请求函数?
function retryRequest(requestFn, retries = 3, delay = 1000) {
return new Promise((resolve, reject) => {
const attempt = (n) => {
requestFn()
.then(resolve)
.catch((err) => {
if (n <= 0) {
reject(err)
} else {
console.log(`重试第 ${retries - n + 1} 次...`)
setTimeout(() => attempt(n - 1), delay)
}
})
}
attempt(retries)
})
}
使用示例
function fetchUser() {
return fetch('/api/user').then(r => {
if (!r.ok) throw new Error('请求失败')
return r.json()
})
}
retryRequest(fetchUser, 3, 1000)
.then(user => console.log('成功:', user))
.catch(err => console.log('重试 3 次后仍失败:', err))
进阶:指数退避
function retryWithBackoff(fn, retries = 3, baseDelay = 1000) {
return new Promise((resolve, reject) => {
const attempt = (n) => {
fn()
.then(resolve)
.catch((err) => {
if (n <= 0) {
reject(err)
} else {
const delay = baseDelay * Math.pow(2, retries - n)
console.log(`第 ${retries - n + 1} 次重试,等待 ${delay}ms`)
setTimeout(() => attempt(n - 1), delay)
}
})
}
attempt(retries)
})
}
async/await 版
async function retry(fn, retries = 3, delay = 1000) {
try {
return await fn()
} catch (err) {
if (retries <= 0) throw err
await new Promise(r => setTimeout(r, delay))
return retry(fn, retries - 1, delay)
}
}
同分类其他题目