Promise 技巧 - 自动重试

在前端开发中,我们经常会使用 Promises 来处理异步操作。但有时候,由于网络延迟或其他原因,我们发起的请求可能会失败,导致返回的 Promise 状态为 rejected。

为了确保操作成功,我们通常需要重复尝试请求,直到成功为止。本文将讲述如何使用 Promise 实现自动重试。

基本方法

最简单的实现方式是不断地在 catch 方法中再次发起请求,直到成功或达到重试次数上限。例如:

-------- ------------------- -------- ------- - -- ----- - ----- -
  ------ ---------- --------
    ---------------------- -
      ------------------ -------- ------- --------- --------------
      -- -------- - -- -
        ------ --- ------------------------- -
          ------------------- -------
        ------------------ -
          ------ ------------------- -------- ------- - -- -------
        ---
      - ---- -
        ----- ------
      -
    ---
-

--------------------------------------------------- -
  -- ------ --------
---

该方法依赖递归和 Promise 的链式调用,实现了在请求失败时自动重试的功能。但这里有一个问题,如果最初的请求成功了,我们也会重试两次。为了避免这种情况,我们可以使用 Promise.then 将递归放在 Promise 内部:

-------- ------------------- -------- ------- - -- ----- - ----- -
  ------ ---------- --------
    ---------------------- -
      ------------------ -------- ------- --------- --------------
      ------ --- ------------------------- -
        ------------------- -------
      ------------------ -
        -- -------- - -- -
          ------ ------------------- -------- ------- - -- -------
        - ---- -
          ----- ------
        -
      ---
    ---
-

--------------------------------------------------- -
  -- ------ --------
---

现在,我们不再需要递归调用 Promise 了,而是在 Promise 中创建了一个新的 Promise,用于控制重试次数和延迟。

更灵活的实现方式

以上方法适用于简单的请求和少量的重试次数,但有些情况下,我们需要更复杂的逻辑来处理自动重试。例如,我们可能需要在不同的错误码下采取不同的重试策略,或者根据每次失败的延迟时间动态调整下一次重试的间隔。

在这种情况下,我们可以使用一个专门处理 Promise 的库,如 Bluebird,它提供了更丰富的 Promise 扩展方法和可配置选项。例如,以下代码使用 Bluebird 的 retry 方法来尝试请求,如果达到最大重试次数仍然失败,则返回一个 rejected 状态的 Promise:

----- ------- - --------------------

-------- ------------------- -------- ------- - -- ----- - ----- -
  ------ --- ------------------------- ------- -
    -------- ----------- -
      ---------- -------------------------------------------- -
        ------------------ -------- ------- --------- --------------
        --------------
      ---
    -

    ------------

    -- -------- - -- -
      --------------
        - 
          ---------- -------- 
          --------- ------ 
          ---------- --------------- - 
            -------------------
            ------ ----- 
          -
        --
        ---------
      ----------------
    -
  ---
-

--------------------------------------------------- -
  -- ------ --------
---

在此示例中,我们仍然使用了递归来控制重试次数和延迟,但轮询的细节由 Bluebird 库代理。注意,我们在 catch 方法中使用 reject 而不是 throw,以便在多个尝试请求后返回 rejected 状态的 Promise。

总结

使用 Promise 实现自动重试不仅可以提高可靠性,还可以减小程序的复杂性和减少出现意外错误的概率。以适当的方式使用 Promise 和递归,或使用更高级的库,如 Bluebird,可以帮助我们更好地管理和优化异步操作。

本文介绍了基本的实现方法和更灵活的实现方式,你可以根据具体的需求和场景来选择最适合的方法。希望这些技巧对你的工作有所帮助!

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/664bf743d3423812e4acdba1