ES6 新特性:Promise 详解和使用

阅读时长 8 分钟读完

什么是 Promise

PromiseES6 中新增的一种异步编程解决方案。它可以将异步操作转换成同步操作,并封装了异步操作的结果,方便我们处理异步任务。 Promise 的设计思想主要是基于 callback hell 的问题来解决的。

ES6 之前,在处理异步操作的时候,我们通常会使用回调函数来处理异步结果。例如:

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

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

回调函数的问题在于只能处理一次异步操作,当异步操作嵌套多层时,我们就会陷入 callback hell

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

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

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

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

以上是两层嵌套的异步回调函数,如果我们再多嵌套一层,就会让代码变得不可维护,而 Promise 就是解决这个问题的方案。

Promise 的基本用法

ES6 中,我们可以使用 Promise 来代替异步回调函数,以下是使用 Promise 的基本格式:

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

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

其中:

  • Promise 构造函数接收一个函数作为参数,该函数有两个参数:resolvereject,分别代表异步操作成功和失败时的回调函数。
  • 异步操作成功时,调用 resolve 方法并传递结果;异步操作失败时,调用 reject 方法并传递错误信息。
  • then 方法处理异步操作成功的结果,catch 方法处理异步操作失败的结果。

Promise 的进一步使用

Promise 进一步提供了以下方法:

Promise.all

Promise.all 方法接收一个数组作为参数,当数组内所有 Promise 对象状态都变为 resolved 时,返回一个新的 Promise 对象,回调函数会收到一个数组作为参数,数组内元素分别对应参数数组内正向 Promise 解析为的值。

示例代码:

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

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

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

Promise.race

Promise.race 方法同样接收一个数组作为参数,但是数组内元素只要有一个状态变更,立即将该 Promise 对象返回,回调函数只传递这个变更完毕的实例的解析值或解析拒绝(resolve/reject)状态。

示例代码:

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

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

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

Promise 的链式调用

由于 Promise 对象的返回值与参数之间存在着联系,因此可以进行链式调用。

示例代码:

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

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

在上述代码中,我们通过 then 方法来达到异步函数的链式调用,实现了异步函数的顺序执行。

Promise 的错误捕获

在使用 Promise 进行异步编程时,也需要注意错误处理,如果没有对 Promise 的错误进行捕获,就会导致程序出现未知错误,而且这些错误很难捕获。

实际上,Promise 提供了 catch 方法,用于捕获异步操作失败的情况,类似于 try...catch 语法。

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

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

上面的代码中,我们在 then 方法外部添加了一个 catch 方法,用于捕获状态为 rejectedPromise 对象,如果异步操作出现了错误,就会输出 error

Promise 的可取消性

ES6 中,Promise 提供了一个 abort 方法,用于取消异步任务,防止由于网络等原因导致的长时间等待。

示例代码:

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

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

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

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

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

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

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

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

以上代码中,我们使用 wrapperPromise 存储一个 Promise 实例,同时使用了 abort 方法。当执行到 Promise.race 的时候,我们将 wrapperPromise 和一个计时器实例用数组包起来,代表两个异步操作。在 setTimeout 中,我们会将 abort 方法调用,导致异步任务被停止执行。

结束

以上是 ES6Promise 的详解和使用, Promise 可以有效地解决异步编程中的问题,避免了回调函数嵌套过多,提高了代码的可读性和可维护性。Promise 在实际项目中使用比较频繁,需要我们掌握好它的特性和使用方法。

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

纠错
反馈

纠错反馈

程序员教程

精选优质教程,助你快速提升技术实力

程序员面试题库

海量优质面试题,助你轻松应对技术面试