Promise 链式调用时的异常场景探究

阅读时长 6 分钟读完

引言

随着前端技术的不断进步,Promise 已经成为了异步编程的主流方式之一。而 Promise 的链式调用方式可以让我们更加方便地处理异步任务,同时也有些地方需要我们格外注意,因为 Promise 链式调用时会有一些有趣的异常场景。本文将围绕这些场景展开探究,以期为大家提供参考并尽可能详尽地解答各位的疑惑。

Promise 链式调用基础知识

在开始探究之前,我们先来复习一下 Promise 链式调用的基础知识。

Promise 链式调用就是将多个 Promise 实例串联起来,通过 then 方法传递数据、错误等信息,并继续返回一个 Promise 实例。例如:

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

上面的代码中,第一个 then 方法的回调函数返回了一个字符串 "success",而第二个 then 方法的回调函数则用这个返回值来进行处理。可以看到,当 Promise 实例的状态变为 resolved 并执行完后,就会调用 then 方法中的回调函数。

需要注意的是,如果前一个 Promise 实例中出现了错误,就会跳过后续的 then 方法直接执行 catch 方法的回调函数或抛出异常,例如:

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

上面的代码中,Promise 实例返回的是一个 rejected 状态,因此直接执行了 catch 方法的回调函数,输出了错误信息。

Promise 链式调用的异常场景

忘记返回 Promise 实例

在 Promise 链式调用过程中,前一个 Promise 实例返回的状态决定了后续代码的执行顺序,我们需要保证在 then 方法中返回一个 Promise 实例,否则就会出现代码执行顺序不符合预期的问题。

例如,下面的示例中就是没有返回 Promise 实例时的情况:

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

上面的代码中,第二个 then 方法并没有得到真正的 Promise 实例,因此不会执行其回调函数。

正确的方式是返回一个 Promise 实例,例如:

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

在 Promise 链式调用中抛出异常

在 Promise 链式调用中,如果在 then 方法中抛出异常,就会跳过后续 then 方法直接执行 catch 方法的回调函数或抛出异常。下面的代码就是抛出异常时的场景:

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

上面的代码中,第一个 then 方法抛出了异常,因此直接执行了 catch 方法的回调函数,输出了错误信息。

在异步代码中处理异常

在异步代码中抛出异常时,因为异步的原因我们很难立即得知异常情况,因此我们经常会使用 try...catch 语句块来处理异常。

但是在使用 Promise 链式调用时,因为 then 方法中的代码会异步执行,try...catch 语句块无法捕获到其中的异常。

例如,下面的代码中使用 try...catch 语句块尝试捕获 then 方法中的异常:

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

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

上面的代码中,虽然我们在 then 方法中抛出了异常,但是 try...catch 语句块无法捕获到此异常,因为 Promise 的执行是异步的。

正确的方式是在 then 方法中处理异常:

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

上面的代码中,我们在异步代码中通过 try...catch 语句块捕获了异常,并将异常信息 reject 出去进行下一步处理。

总结

通过本文的探究,我们发现 Promise 链式调用时确实存在一些异常场景需要我们格外注意。如果不遵循 Promise 链式调用的规则,就会导致代码执行顺序出现问题或者异常无法被捕获。

因此,在使用 Promise 链式调用时,我们需要遵循 Promise 链式调用的规则,以及注意异常场景的处理方式,让我们的代码更加健壮。

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

纠错
反馈