Promise 的 then 方法和 catch 方法同时执行的原因

阅读时长 4 分钟读完

在 JavaScript 中,Promise 是一种管理异步操作的方式,可以用来避免回调地狱。Promise 对象有两个重要的方法:then 方法和 catch 方法。当 Promise 对象状态变为 resolved 时,then 方法会被调用;当状态变为 rejected 时,catch 方法会被调用。在某些情况下,then 方法和 catch 方法会同时被执行,这可能会对程序执行产生意外的结果。在本文中,我们将探讨为什么 then 方法和 catch 方法同时执行,并提供一些指导意义,以帮助您更好地使用 Promise。

Promise 状态转换

在了解为什么 then 方法和 catch 方法同时执行之前,让我们先了解一下 Promise 的状态转换。Promise 有三种状态:pending、resolved 和 rejected。

当 Promise 对象被创建时,其状态为 pending。当执行异步操作后,promise 对象的状态会变成 resolved 或 rejected。如果异步操作成功,状态将变为 resolved,否则将变为 rejected。

以下是创建 Promise 对象的示例代码:

在上面的代码中,myPromise 对象的状态将根据异步操作的结果而变成 resolved 或 rejected。

then 方法和 catch 方法的执行顺序

Promise 对象状态变为 resolved 后,then 方法会被执行;状态变为 rejected 后,catch 方法会被执行。根据 Promise/A+ 的规范,then 方法和 catch 方法是异步执行的,因此它们的执行顺序是不可预测的,可能会同时执行。这种情况通常出现在 Promise 链式调用的情况下。

以下是一个 Promise 链式调用的示例代码:

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

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

在上面的代码中,当 Promise 对象状态变为 resolved 时,then 方法会被执行,并输出 "then 方法被调用";当状态变为 rejected 时,catch 方法会被执行,并输出 "catch 方法被调用"。但是,由于 then 方法和 catch 方法是异步执行的,因此存在一种可能性,即它们的执行顺序是不可预测的,可能会同时执行。以下是一种可能的输出:

在这种情况下,catch 方法和 then 方法都被执行了,这可能会对程序执行产生意外的结果。

解决方案

为了避免 then 方法和 catch 方法同时执行,可以使用 Promise.prototype.finally() 方法。该方法在 Promise 对象状态变化后都会执行,不管状态是 resolved 还是 rejected。

以下是示例代码:

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

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

在上面的代码中,无论是状态变为 resolved 还是 rejected,finally 方法都会被执行。

结论

Promise 的 then 方法和 catch 方法都是异步执行的,因此它们的执行顺序是不可预测的,可能会同时执行。为了避免这种情况,可以使用 Promise.prototype.finally() 方法。在编写 Promise 代码时,需要充分考虑这一点,以避免出现意外的结果。

参考链接

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

纠错
反馈