异步容错实战:基于promise的请求重试

失败重试是 对可能失败的操作进行自动重复尝试的容错机制。比如前端支付场景,如果首次请求超时,可以尝试重试 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 函数通过 闭包管理重试次数递归调用 实现了对异步操作的自动重试机制,核心逻辑如下:

  1. 控制次数
    使用 count 变量记录当前尝试次数,确保每次失败后递增并校验是否超过 maxTimes,避免无限重试。
  2. 递归发起请求
    通过 repeat 函数递归调用自身,在失败时触发下一次尝试。借助 Promise 的链式调用,将异步操作串联,直至成功或达到最大次数。
相关推荐
胖墩会武术15 分钟前
通过Auto平台与VScode搭建远程开发环境(以Stable Diffusion Web UI为例)
前端·vscode·stable diffusion
未来之窗软件服务1 小时前
封装拍照模块,拓展功能边界—仙盟创梦IDE
前端·javascript·html·摄像头·仙盟创梦ide
源力祁老师2 小时前
Odoo: Owl Props 深度解析技术指南
前端·javascript·网络
BillKu2 小时前
Vue3 Element Plus el-table-column Sortable 排序失效
javascript·vue.js·elementui
Liu.7742 小时前
vue3样式穿透用法
前端·vue.js·elementui
捡星星同学2 小时前
el-table高度自适应、数据查询后高度展示错误问题
javascript·vue.js·elementui
SYKMI4 小时前
@JsonFormat时区问题
java·前端·数据库
海盐泡泡龟6 小时前
web常见的攻击方式有哪些?如何防御?
前端·vue.js·webpack
EndingCoder8 小时前
React从基础入门到高级实战:React 基础入门 - React Hooks 入门
前端·javascript·react.js·前端框架
EndingCoder8 小时前
React从基础入门到高级实战:React 基础入门 - JSX与组件基础
前端·javascript·react.js·前端框架