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