Promises 是 ECMAScript 2015 中引入的一种异步编程模式,它可以方便地处理异步操作的结果,以及避免回调嵌套的问题。在 ECMAScript 2020 中,Promises 得到了一些优化和扩展,使得它们更加灵活和易用。
优化和扩展
可处理的错误
在早期的 Promises 实现中,错误处理往往是比较麻烦的。通常需要在 Promise 的链式调用中使用 .catch()
方法来捕获错误,或者使用 try-catch
语句来处理。但是这样的做法往往会导致代码冗长和不易维护。
在 ECMAScript 2020 中,Promises 的错误处理得到了改进。现在,Promise 的构造函数可以接受一个可选的 onRejected
参数,用于处理 Promise 被拒绝时的错误。例如:
-- -------------------- ---- ------- ----- ------- - --- ----------------- ------- -- - -- ---- ------------ --------- -- --- --------- -------- --- - ---------------- - ---- - ---------- ---------------- ---------- - -------------- -- - --------------------- ---展开代码
在上面的例子中,我们在 Promise 的构造函数中传入了一个 reject
函数,用于处理 Promise 被拒绝时的错误。如果 Promise 被拒绝,就会调用传入的 onRejected
函数,并将错误作为参数传递给它。这样就可以避免在 Promise 链式调用中使用 .catch()
方法来捕获错误。
新的静态方法
在 ECMAScript 2020 中,Promise 类新增了一些静态方法,使得 Promises 更加灵活和易用。
Promise.allSettled()
Promise.allSettled()
方法接受一个 Promise 数组作为参数,并返回一个新的 Promise,该 Promise 在所有 Promise 都完成后解决。与 Promise.all()
方法不同的是,即使其中有 Promise 被拒绝,Promise.allSettled()
也会在所有 Promise 完成后解决,并返回一个数组,数组中包含每个 Promise 的状态和结果。例如:
-- -------------------- ---- ------- ----- -------- - - --------------------------- ------------------ ------------------ ------------------------ --------- -- ----------------------------------------- -- - --------------------- -- ------- -- - -- - ------- ------------ ------ --------- -- -- - ------- ----------- ------- ------ ------- -- ----------------- -- -- - ------- ------------ ------ -------- -------- - -- - ---展开代码
在上面的例子中,我们创建了一个包含三个 Promise 的数组,并使用 Promise.allSettled()
方法来等待所有 Promise 完成。即使其中有 Promise 被拒绝,最终的结果数组中仍然包含所有 Promise 的状态和结果。
Promise.any()
Promise.any()
方法接受一个 Promise 数组作为参数,并返回一个新的 Promise,该 Promise 在其中任何一个 Promise 解决后解决。如果所有 Promise 都被拒绝,Promise.any()
方法将返回一个 AggregateError 对象,该对象包含所有 Promise 的错误。例如:
-- -------------------- ---- ------- ----- -------- - - ------------------ -------------- ----- --------------------------- ------------------ -------------- ---- -- --------------------------------- -- - -------------------- -- ------- ------- -------------- -- - --------------------- -- ------- --------------- --- -------- ---- -------- ---展开代码
在上面的例子中,我们创建了一个包含三个 Promise 的数组,并使用 Promise.any()
方法来等待其中任何一个 Promise 解决。由于其中一个 Promise 被解决了,最终的结果为成功。如果所有 Promise 都被拒绝,Promise.any()
方法将抛出一个 AggregateError 对象,该对象包含所有 Promise 的错误。
Promise.try()
Promise.try()
方法接受一个函数作为参数,并返回一个新的 Promise,该 Promise 在函数执行完成后解决。与普通的函数调用不同的是,Promise.try()
方法会自动捕获函数执行过程中的错误,并将其作为 Promise 的拒绝原因。例如:
const fn = () => { throw new Error('failure'); }; Promise.try(fn).catch(error => { console.error(error); // Output: Error: failure });
在上面的例子中,我们定义了一个会抛出错误的函数 fn
,并使用 Promise.try()
方法来调用它。由于 Promise.try()
方法会自动捕获错误,因此我们可以在 Promise 链式调用中使用 .catch()
方法来处理错误。
示例代码
下面是一个使用 ECMAScript 2020 中的 Promises 的例子:
-- -------------------- ---- ------- ----- --------- - -- -- - ------ --- ----------------- ------- -- - ------------- -- - ----- ---- - - ----- -------- ---- -- -- -------------- -- ------ --- -- ----- ---------- - -------- -- - ------ --- ----------------- ------- -- - ------------- -- - ----- ----- - - - --- -- ------- ------ ----- -- -- - --- -- ------- ------ ----- -- -- - --- -- ------- ------ ----- -- - -- --------------- -- ------ --- -- ----- ------------- - -------- -- - ------ --- ----------------- ------- -- - ------------- -- - ----- -------- - - - --- -- ------- ----- -------- -- -- - --- -- ------- ----- -------- -- -- - --- -- ------- ----- -------- -- - -- ------------------ -- ------ --- -- ----- ------ - -- -------------- -- - ------ ------------ ------------ -- - ------------------ ------ -------------------- ------------- -- - ------------------- ----- -------- - -------------- -- ------------------------ ------ ----------------------------- --------------- -- - --------------------- -------------- -- - --------------------- ---展开代码
在上面的例子中,我们定义了三个异步函数 fetchUser()
、fetchPosts()
和 fetchComments()
,分别用于获取用户、帖子和评论。我们使用 Promise 的链式调用来依次调用这三个函数,并在最后使用 Promise.allSettled()
方法来等待所有评论的 Promise 完成。在 Promise 的构造函数中使用 reject
函数来处理 Promise 被拒绝时的错误,避免了在 Promise 链式调用中使用 .catch()
方法来捕获错误。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d937c2a941bf71340c3f48