JavaScript 中的 Promises 和错误处理

阅读时长 6 分钟读完

摘要

Promises 是 JavaScript 中的一种处理异步操作的技术,通过返回一个 Promise 对象来解决回调地狱的问题,同时也提供了一种更加灵活的错误处理方式。 本文将详细介绍 Promises 的概念、用法以及如何在代码中正确处理 Promise 中的错误。

什么是 Promise?

在 JavaScript 中,对于一些可能需要时间的操作(如从服务器获取数据等),我们通常会使用异步操作,避免因等待数据而阻塞整个程序。但是,异步操作的结果我们通常需要通过回调函数来处理,而多层嵌套的回调函数(也就是所谓的回调地狱)使得代码变得难以理解和维护。

Promises 提供了一种解决方案。Promise 可以被看作是一个操作的异步结果的占位符,该结果可能会在未来某个时间点被满足。一个 Promise 对象有三种状态:pending(等待中)、fulfilled/resolved(已满足/已解决)和rejected(已拒绝)。

在一个 Promise 对象上可以调用 then() 方法注册一系列的回调函数,用于处理异步操作的结果。 then() 方法接收一个或者两个回调函数作为参数。第一个回调函数用于处理操作成功的情况,第二个回调函数用于响应操作失败的情况。当 Promise 对象被满足或者拒绝时,它们所注册的回调函数就会被自动执行。

以下是一个简单的 Promise 对象实现及其调用代码示例:

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

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

该示例中,我们创建了一个 Promise 对象,该对象在一秒钟后返回一个成功的结果或一个失败的错误。我们注册了两个回调函数,当 Promise 对象被解决时这两个回调函数将会被自动执行,成功情况的回调函数将打印结果,错误情况的回调函数则会打印错误信息。

如何处理 Promise 的错误?

在使用 Promise 的过程中,错误处理是一个不可忽视的问题。下面我们来介绍在 Promise 的错误处理中应该注意的细节。

then() 中处理错误

在使用 Promise 时,我们可以在 then() 中传入两个回调函数(一个用于处理成功的情况,一个用于处理失败的情况)。在成功的情况下,第一个回调函数被调用;在失败的情况下,第二个回调函数被调用。如果在一个 Promise 链中有多个 then(),则每个 then() 中都可以有错误处理逻辑。

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

在这个例子中,我们使用 fetch API 来异步获取 JSON 数据。如果获取数据成功,则打印结果,否则打印错误信息。

同样,我们也可以在第二个 then() 中添加错误处理逻辑。如果我们在处理上一个 Promise 对象的 then() 方法时返回一个新的 Promise 对象,那么在下个 then() 方法中也可以添加错误处理逻辑,并且它会处理所有在之前新创建的 Promise 对象上发生的错误。

catch() 中处理错误

除了在 then() 中处理错误之外,我们还可以使用 catch() 来处理 Promise 的错误。catch() 能够捕捉 Promise 链中任何一个 Promise 失败时所抛出的错误。这种错误处理方式类似于 try/catch 块的工作方式。

如果 Promise 链中 then() 函数中的回调函数或者 Promise 对象中的异步操作中出现了异常,则 catch() 中的回调函数会被调用。

错误处理最佳实践

在处理 Promise 的错误时,以下是一些最佳实践:

  • then() 方法中返回一个新的 Promise 对象,而不是在回调函数中抛出异常。这样可以确保在 Promise 链中的所有 Promise 对象中都可以处理错误。
  • 在 Promise 链的末尾使用 .catch() 方法处理所有未处理的错误。
  • 对于可恢复的错误(例如网络请求失败),为每个失败的操作都显示错误消息,但仍然返回一个新的 Promise 对象并继续执行后续操作。如果是不可恢复错误(例如数据库连接失败),则直接拒绝 Promise 对象。

下面是一个例子:

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

该示例中,我们首先对获取数据的 HTTP 状态码进行校验,如果不是 200 OK,就抛出一个错误。我们在第一个 then() 中处理错误,并在之后的 catch() 中添加一个错误处理函数。如果代码中抛出了其他错误,则也会在 catch() 中被捕获并进行处理。最后,我们可以在 displayErrorMessage() 中显示错误信息。

结论

Promise 提供了一种优雅的方式来处理异步操作的结果,并且提高了代码的可读性和可维护性。在处理 Promise 必须时刻注意错误处理的细节,以确保代码能够安全地运行。通过适当的错误处理方式,我们可以更好地控制程序的运行流程,并且在异常情况下执行适当的回滚操作,从而保证程序在任何情况下都能稳定运行。

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

纠错
反馈