ES9 之如何解决 Promise 异常中断的问题

阅读时长 6 分钟读完

Promise 是 JavaScript 中常用的异步编程解决方案,但是在实际使用中,我们经常会遇到 Promise 执行过程中出现异常而导致中断的问题。这种情况下,我们需要找到一种解决方案来尽可能地减少异常对程序的影响。在 ES9 中,为了解决这个问题,引入了一个新的原型方法:Promise.prototype.finally()

Promise 举例

为了更好地说明 Promise 异常中断的问题,让我们首先看一下一个 Promise 的简单示例。

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

-------
  -------------- -- -
    --------------------
  --
  -------------- -- -
    -------------------
  ---
展开代码

这里定义了一个 Promise,它会在 1 秒后随机返回一个结果,如果返回结果是大于 0.5 的随机数,则调用 resolve() 方法,否则调用 reject() 方法。接着,我们在 Promise 上调用了 then()catch() 方法,分别用于处理 Promise resolve 或 reject 的结果。

Promise 异常中断的问题

在上面的例子中,如果 Promise 在执行过程中出现异常,则会直接中断程序的执行。例如,我们可以向定时器中传递一个无效的参数,从而使程序引发异常:

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

-------
  -------------- -- -
    --------------------
  --
  -------------- -- -
    -------------------
  ---
展开代码

在这个例子中,我们将定时器的延迟时间设置为一个无效的字符串值 'invalid',这会引发一个 TypeError 异常,从而中断程序的执行。这种情况下,我们的 Promise 的 then()catch() 方法都不会被调用。

Promise.prototype.finally() 方法

为了解决上述问题,ES9 新引入了一个 finally() 方法,该方法可以让我们在 Promise resolve 或 reject 完成后执行一些必要的清理工作。

finally() 方法可以接受一个回调函数作为参数,该回调函数会在 Promise resolve 或 reject 完成后被调用。在回调函数执行完毕后,finally() 方法会返回一个新的 Promise 对象,它的状态和原来的 Promise 对象一致。

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

-------
  -------------- -- -
    --------------------
  --
  -------------- -- -
    -------------------
  --
  ----------- -- -
    -------------------- -----------
  ---
展开代码

在这个例子中,我们在 Promise 上调用了 finally() 方法,在该方法中传递了一个回调函数。在这个回调函数中,我们输出了一条信息来表示程序已经完成。

深入理解

在Promise 的执行中返回一个正在执行的Promise对象,会导致该对象执行过程的一些错误不会被清理。

例如:

在这个例子中,我们返回了一个执行失败的 Promise 对象。在 catch() 方法中,我们打印了出错信息。然而,在整个 Promise 执行完毕后,finally() 方法中定义的语句仍会全部执行。

如何解决这个问题?事实上,我们只需要将返回的 Promise 对象再次或设置 catch 的函数来清理 Promise 内的错误即可。

在这个例子中,当 Promise 对象失败时,第一个 catch() 方法将会打印出错信息。而在 finally() 方法中定义的语句执行完毕后,由于还定义了第二个 catch() 方法,因此我们可以在这个方法中继续清理 Promise 内的错误(在本例中,我们只是简单地打印了一条信息)。

总结

Promise 是 JavaScript 中的一种异步编程解决方案,由于经常存在异常中断的问题,ES9 引入了 Promise.prototype.finally() 方法,该方法可以让我们在 Promise resolve 或 reject 完成后执行一些必要的清理工作。在使用该方法时,我们还需要注意对 Promise 内的错误进行清理,避免可能导致的错误或异常。

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

纠错
反馈

纠错反馈