Promise 中 then 和 catch 执行顺序问题详解

阅读时长 8 分钟读完

Promise 是前端开发中常用的异步编程方法之一,但是在使用 Promise 的时候,经常会遇到其中 then 和 catch 的执行顺序问题,特别是当 Promise 链式调用的时候,更需要注意这个问题。本文将详细讲解 Promise 中 then 和 catch 的执行顺序问题,并给出一些示例代码帮助读者更好地理解以及掌握这个问题。

Promise 是什么?

Promise 是一种表示异步操作的对象,可以看作是异步编程的一种解决方案。它提供了状态转换机制,可以表示异步操作成功、失败、或者正在进行中等状态。Promise 对象最终将变成两种状态之一:resolved(成功)或 rejected(失败)。并且,通过 then 和 catch 方法可以注册回调函数,用于在 Promise 对象的状态发生变化后执行自定义的操作。

then 和 catch

Promise 中的 then 和 catch 方法用于注册当 Promise 对象状态变化之后需要执行的回调函数。then 方法用于注册当 Promise 对象已成功时需要执行的回调函数,而 catch 方法用于注册当 Promise 对象被拒绝时需要执行的回调函数。

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

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

在上面的示例中,我们创建了一个 Promise 对象,设置了一个 1 秒的定时器,然后在定时器回调函数中使用 resolve 方法将 Promise 对象转换成 resolved 状态,并传递了一个参数 "Hello World"。接着,我们使用 then 方法注册了一个回调函数,用于处理 Promise 对象状态已成功的情况,这个回调函数会输出 "Resolved: Hello World"。如果 Promise 对象变成 rejected 状态,则会执行 catch 方法注册的回调函数。

需要注意的是,通过 then 方法注册的回调函数必须返回一个值,这个值可以是一个新的 Promise 对象,也可以是一个非 Promise 对象的值。如果返回的是一个新的 Promise 对象,那么需要等待这个新的 Promise 对象状态改变之后,才会执行下一个 then 或者 catch 方法的回调函数。如果返回的是一个非 Promise 对象的值,则会将这个值包装成一个 Promise 对象,并立即执行下一个 then 或者 catch 方法的回调函数。

then 方法执行顺序

在使用 then 方法时,可以链式调用多个 then 方法,每个 then 方法注册的回调函数可以根据之前 then 方法返回的值来确定最终返回的值。而在这个过程中,then 方法的执行顺序是非常关键的。一般来说,then 方法注册的回调函数会按照注册的顺序依次执行,也就是说,后注册的回调函数会等待前面的回调函数执行完毕才会开始执行。

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

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

在上面的示例中,我们创建了一个 Promise 对象,设置了一个 1 秒的定时器,然后在定时器回调函数中使用 resolve 方法将 Promise 对象转换成 resolved 状态,并传递了一个参数 1。接着,我们使用 then 方法连续注册了三个回调函数,每个回调函数都会将上一个回调函数的返回值加上 1 并作为自己的返回值。在输出结果中可以看到,第一个 then 方法的回调函数会在 1 秒后执行并输出 "first then: 1",第二个 then 方法的回调函数会在第一个回调函数执行完毕之后执行,并输出 "second then: 2",第三个 then 方法的回调函数也会等待前面的回调函数执行完毕之后执行,并输出 "third then: 3"。

catch 方法执行顺序

和 then 方法类似,catch 方法也支持链式调用,每个 catch 方法注册的回调函数会按照注册的顺序依次执行,也就是说,后注册的回调函数会等待前面的回调函数执行完毕才会开始执行。

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

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

在上面的示例中,我们创建了一个 Promise 对象,设置了一个 1 秒的定时器,然后在定时器回调函数中使用 reject 方法将 Promise 对象转换成 rejected 状态,并传递了一个 Error 对象。接着,我们使用 catch 方法连续注册了两个回调函数,每个回调函数都会输出上一个回调函数的错误信息。在输出结果中可以看到,第一个 catch 方法的回调函数会在 1 秒后执行并输出 "first catch: Something went wrong",第二个 catch 方法的回调函数会等待第一个回调函数执行完毕之后执行,并输出 "second catch: Something went wrong"。

then 和 catch 执行顺序问题

当 Promise 对象状态变成 resolved 时,注册的 then 方法会依次执行,直到所有的 then 方法执行完毕。当 Promise 对象状态变成 rejected 时,注册的 catch 方法会依次执行,直到所有的 catch 方法执行完毕。但是,如果在 Promise 链式调用中,某个 then 方法传递给下一个 then 方法的是一个 rejected 状态的 Promise 对象,那么直接跳到下一个 catch 方法,不再执行后续的 then 方法。因此,then 和 catch 的执行顺序问题,就是指当 Promise 对象状态发生变化时,then 和 catch 方法的执行顺序有哪些特点和需要注意的地方。

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

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

在上面的示例中,我们创建了一个 Promise 对象,设置了一个 1 秒的定时器,然后在定时器回调函数中使用 reject 方法将 Promise 对象转换成 rejected 状态,并传递了一个 Error 对象。接着,我们使用 then 方法注册了一个回调函数,然后又使用一个 then 方法注册了另一个回调函数。此时,由于 Promise 对象的状态已经变成 rejected,因此会直接跳到 catch 方法,并执行 catch 方法的回调函数。在输出结果中可以看到,程序会输出 "Catch: Something went wrong",而不会执行后面那个 then 方法的回调函数。

总结

Promise 是前端开发中常用的异步编程方法之一,在使用 Promise 的过程中,then 和 catch 方法是非常重要的一部分。理解并掌握 then 和 catch 方法的执行顺序问题,是编写高质量代码的关键之一。在编写代码时,需要根据具体业务场景合理地选择使用 then 和 catch 方法,才能使代码更加健壮、高效。下面是一些需要注意的地方:

  1. then 方法的回调函数需要返回一个值,可以是一个新的 Promise 对象,也可以是一个非 Promise 对象的值。

  2. 在 Promise 链式调用中,如果某个 then 方法传递给下一个 then 方法的是一个 rejected 状态的 Promise 对象,直接跳到下一个 catch 方法,不再执行后续的 then 方法。

  3. then 方法注册的回调函数会按照注册的顺序依次执行,后注册的回调函数会等待前面的回调函数执行完毕才会开始执行。

  4. catch 方法也支持链式调用,每个 catch 方法注册的回调函数会按照注册的顺序依次执行,后注册的回调函数会等待前面的回调函数执行完毕才会开始执行。

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

纠错
反馈