如何实现一个带重试机制的请求函数?

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)
  })
}
// 延迟:1s → 2s → 4s

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)
  }
}

同分类其他题目