30 分钟掌握 Promise

阅读时长 7 分钟读完

前言

在 Web 前端开发中,异步操作是非常常见的,常用的异步操作包括异步请求、异步渲染组件、异步加载资源等等。而在异步操作过程中,我们经常会遇到异步嵌套带来的回调地狱问题,这种问题导致程序可读性变差,阅读和维护难度大。

Promise 被众多前端开发者用来解决回调地狱问题,自诞生以来就受到了大家的欢迎。在这篇文章中,我将教大家如何在 30 分钟内掌握 Promise。

Promise 是什么?

Promise 是 JavaScript 中的一个对象,可以代表异步操作的最终完成状态(成功或失败)以及它的返回值。Promise 分为三种状态:Pending(进行中)、Fulfilled(已成功)和 Rejected(已失败)。

Promise 对象本身是一个构造函数,具有以下常用方法:

  • new Promise():创建一个新的 Promise 对象。
  • Promise.prototype.then():在 Promise 对象状态变为 Fulfilled 或 Rejected 时调用。
  • Promise.prototype.catch():捕获 Promise 对象状态为 Rejected 的异常。
  • Promise.prototype.finally():添加一个回调函数,不管 Promise 对象状态变为什么都会调用。

Promise 的工作原理

Promise 的工作原理可以通过以下代码来解释:

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

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

首先我们创建一个新的 Promise 对象,并传入一个回调函数,这个回调函数又包含两个参数:resolve 和 reject。在回调函数中,我们使用 setTimeout 模拟一个异步操作,一秒后调用 resolve 方法表示异步操作成功,并且传入了一个字符串参数。而如果异步操作失败,我们则调用 reject 方法,并传入一个 Error 对象作为参数。

在 Promise 对象的 then 方法中,我们传入了一个回调函数,这个回调函数会在 Promise 对象状态变为 Fulfilled 后被调用,并且接收到 resolve 方法中传递的参数。而在 Promise 对象的 catch 方法中,我们传入了另一个回调函数,这个回调函数会在 Promise 对象状态变为 Rejected 后被调用,并且接收到 reject 方法中传递的 Error 对象作为参数。在 Promise 对象的 finally 方法中,我们添加了一个回调函数,不管 Promise 对象状态变为什么,这个回调函数都会被调用。

Promise 的链式调用

在使用 Promise 的时候,我们通常会将一个异步操作封装在 Promise 对象中,然后通过链式调用的方式处理 Promise 对象的状态。以下是一个 Promise 链式调用的例子:

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

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

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

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

在这个例子中,我们封装了三个异步操作的 Promise 对象: step1、step2 和 step3。这三个 Promise 对象都使用 setTimeout 模拟了异步操作,它们依次依赖前一个 Promise 的状态,并且在完成操作后返回新的值。

通过 then 方法,我们将每个操作封装在一个函数中,并将这些函数作为参数传入前一个 Promise 对象的 then 方法中。在每个操作函数中,我们都接收到了前一个操作返回的结果,并将它作为参数传递给下一个操作。

最后,我们使用 then 方法传入一个回调函数,这个回调函数会接收到最后一个操作返回的结果,并打印到控制台上。

Promise.all 的使用

前面我们已经讲过,Promise 对象还有一种 Pending 状态。如果在使用 Promise 的时候,我们需要同时调用多个异步操作,然后等待它们全部完成后再统一处理结果,就需要使用 Promise.all()。

下面是一个使用 Promise.all() 方法来处理多个异步操作的例子:

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

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

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

在这个例子中,我们定义了两个函数 fetchData1 和 fetchData2,用于模拟两个异步操作。然后我们使用 Promise.all 方法来调用这两个函数,它会同时启动这两个异步操作,等待它们全部完成后,将两个操作返回的结果封装在一个数组中传递给回调函数。在回调函数中,我们可以使用数组解构来获取每个异步操作返回的结果,并每个结果相加。

Promise 的指导意义

Promise 是一种非常强大的工具,它可以使我们用更加优雅的方式来处理异步操作,并解决回调地狱的问题。同时,Promise 也是属于比较难以理解的 JavaScript 内容之一。学好 Promise 对于 Web 前端开发人员而言是非常有价值的。

当你掌握了 Promise 之后,你会发现你的代码更加的整洁和易于维护。同时,Promise 也是很多其他工具和框架的基石,如 RxJS、Angular 和 Vue 等,学好 Promise 对其他工具的学习和使用都能给与很大帮助。

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

纠错
反馈

纠错反馈