什么是 Promise
Promise
是 ES6
中新增的一种异步编程解决方案。它可以将异步操作转换成同步操作,并封装了异步操作的结果,方便我们处理异步任务。 Promise
的设计思想主要是基于 callback hell
的问题来解决的。
在 ES6
之前,在处理异步操作的时候,我们通常会使用回调函数来处理异步结果。例如:
-- -------------------- ---- ------- -------- ------------------- - ------------- -- - ----------------- -- ------ - ---------------- -- - -------------------- ---展开代码
回调函数的问题在于只能处理一次异步操作,当异步操作嵌套多层时,我们就会陷入 callback hell
:
-- -------------------- ---- ------- -------- ------------------- - ------------- -- - ----------------- -- ------ - -------- ----------------------- - ---------------- -- - ------------- -- - ------------------- - ---- ------- -- ------ --- - -------- ------------------------- - -------------------- -- - ------------- -- - ------------------- - ---- --------- -- ------ --- - ---------------------- -- - -------------------- ---展开代码
以上是两层嵌套的异步回调函数,如果我们再多嵌套一层,就会让代码变得不可维护,而 Promise
就是解决这个问题的方案。
Promise 的基本用法
在 ES6
中,我们可以使用 Promise
来代替异步回调函数,以下是使用 Promise
的基本格式:
-- -------------------- ---- ------- ----- ------- - --- ----------------- ------- -- - -- ------ ------------- -- - ---------------- -- ----- ------- ------- -- - ---------------- -- ----- ------ ------- -- ------ --- -- ------ ------------------- -- - -------------------- -------------- -- - ------------------- ---展开代码
其中:
Promise
构造函数接收一个函数作为参数,该函数有两个参数:resolve
和reject
,分别代表异步操作成功和失败时的回调函数。- 异步操作成功时,调用
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
方法,用于捕获状态为 rejected
的 Promise
对象,如果异步操作出现了错误,就会输出 error
。
Promise 的可取消性
在 ES6
中,Promise
提供了一个 abort
方法,用于取消异步任务,防止由于网络等原因导致的长时间等待。
示例代码:
-- -------------------- ---- ------- -------- ----------- - ----- ------- - --- ----------------- ------- -- - ------------- -- - ---------------- -- ------ --- ----- ----- - -- -- - ---------------- -- ----- -------------- - -------------- -------- --- ---------- -- - ------------- -- - -------- -- ------ --- --- -------------------- - ------ ------ --------------- - ----- ---------------- - ------------ --------------------------- -- - ----------------- ---------------- -- - ------------------- --- ------------- -- - ------------------------- -- ------展开代码
以上代码中,我们使用 wrapperPromise
存储一个 Promise
实例,同时使用了 abort
方法。当执行到 Promise.race
的时候,我们将 wrapperPromise
和一个计时器实例用数组包起来,代表两个异步操作。在 setTimeout
中,我们会将 abort
方法调用,导致异步任务被停止执行。
结束
以上是 ES6
中 Promise
的详解和使用, Promise
可以有效地解决异步编程中的问题,避免了回调函数嵌套过多,提高了代码的可读性和可维护性。Promise
在实际项目中使用比较频繁,需要我们掌握好它的特性和使用方法。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67b85135306f20b3a65ff2bc