避免 ES8 中 Promise.finally() 陷阱的几种方法

阅读时长 4 分钟读完

Promise.finally() 是 ES8 中引入的新的 Promise 方法,它会在 Promise settled (resolved 或 rejected)后执行,无论 Promise 是否成功都会执行一次。然而,使用 Promise.finally() 时可能会遇到某些坑。本文将介绍一些方法,帮助你避免 Promise.finally() 的陷阱。

陷阱

在 Promise.finally() 中,如果返回一个 rejected Promise 或者抛出异常,会阻止 Promise 的继续执行,导致 Promise 被卡在 settled 状态,然后如果有未处理的 rejected Promise,就会触发 unhandledRejection 事件。看下面的代码:

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

在此代码中,Promise 被卡在 settled 状态,然后会触发 unhandledRejection 事件,表明未处理 rejected Promise,输出 finally error。为了避免这种情况,下面是几种方法。

方法一:返回新的 Promise 对象

Promise.finally() 不返回任何值,它只是为了在 settled 后执行一些代码。可以在 finally() 中,返回一个新的 Promise 对象,以避免阻止 Promise 的继续执行。

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

在此代码中,返回了一个新的 Promise 对象,它会被 rejected,并在 catch() 中捕获,输出 finally error

方法二:使用 Promise.reject() 异常

另一种避免 Promise.finally() 陷阱的方法是在 finally() 中使用 Promise.reject() 异常,而不是 throw:

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

在此代码中,使用了 Promise.reject() 异常,它会返回一个 rejected Promise,然后在 catch() 中捕获,输出 finally error

方法三:在外部 catch() 中处理异常

另一种方法是,在外部使用 catch() 来处理 finally() 中的异常,避免使用 throw 或 Promise.reject()。

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

在此代码中,使用了外部的 catch() 处理错误,避免了在 finally() 中抛出异常。如果 finally() 中没有异常,catch() 只会捕获在 then() 中出现的异常。

结论

在使用 Promise.finally() 时要小心,要避免抛出或返回错误的 Promise 对象,否则可能会导致 unhandledRejection 事件的触发。在使用 finally() 时,可以通过返回新的 Promise 对象或使用外部的 catch() 来避免异常。积极地避免这些陷阱,有助于确保代码的正确性和可读性。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/674d7ad5c90ee1bbd8bb2fb3

纠错
反馈