ES11 中的 Promise.allSettled,解决Promise.all 中的错误抛出问题
在前端开发中,我们经常需要处理异步操作。Promise 是一种很好的异步处理方式,它可以使代码更加清晰和易于维护。在实际应用中,我们经常会遇到一个场景:当多个异步操作都完成后,再去执行下一步操作。为了处理这个场景,ES6提供了 Promise.all 方法,它可以将多个 Promise 实例包装成一个新的 Promise 实例,只有当所有 Promise 都为 fulfilled 状态时,才会调用 then 方法,否则调用 catch 方法。但是,Promise.all 也有一个很大的缺点,当其中一个 Promise 发生错误,Promise.all 会停止执行,并抛出错误,导致其余的 Promise 取消执行。这个问题在开发中常常会遇到,为了解决这个问题,ES11 引入了 Promise.allSettled 方法,其中的每个 Promise 都会执行并返回结果,不管是 fulfilled 还是 rejected 状态,最终返回的数组中每个对象都包括了这个 Promise 状态和值(如果存在)。
Promise.all 和 Promise.allSettled 的比较:
- Promise.all 返回的是一个 Promise 实例,所有的 Promise 在 fulfilled 状态时才会调用 then 方法。如果某一个 Promise 处于 rejected 状态,则会被终止并抛出错误,导致其他 Promise 也无法继续执行。
- Promise.allSettled 返回的是一个 Promise 实例,其中每个 Promise 都会执行并返回结果,不管是 fulfilled 还是 rejected 状态,最终返回的数组中每个对象都包括了这个 Promise 状态和值(如果存在)。
下面是 Promise.all 和 Promise.allSettled 的示例代码:
-- -------------------- ---- ------- ----- -- - ------------------- ----- -- - ------------------- ----- -- - ------------------ -- ----------- -- ---------------- --- ---- ----------- --- ---- -- - ---------------- -- - ---------------- -- - ---------------- -- ------ -- ------------ -- - ----------------- -- - --- -- ------------------ -- ----------------------- --- ---- ----------- --- ---- -- - ---------------- -- -------- ------------ ------ -- ---------------- -- -------- ------------ ------ -- ---------------- -- -------- ----------- ------- -- ---
可以看到,当用 Promise.all 处理多个 Promise 时,其中一个 Promise 处于 rejected 状态,就会导致整个 Promise.all 都为 rejected 状态。而当使用 Promise.allSettled 时,不管其中一个 Promise 何种状态,都会执行并返回一个数组,其中包括每个 Promise 的状态和值(如果存在)。
总结
Promise.all 和 Promise.allSettled 这两个方法都可以处理多个异步操作并等待它们的完成,但是在处理异步操作中的错误时,Promise.all 处理起来更加困难,因为它会终止所有操作并抛出错误。要想处理这个问题,可以使用 Promise.allSettled,因为它会执行所有 Promise,返回结果和状态(无论是否成功)。
Promise.allSettled 是 ES11 引入的新特性,如果你需要处理多个 Promise 且不想在任何结果失败时就立即抛出错误,那么它是一个不错的选择。
当然,细心的读者可能已经注意到,Promise.all 和 Promise.allSettled 的返回值类型不同。前者返回的是一个 Promise 实例,只有在所有异步操作都完成并且都成功时才会返回成功状态。后者返回的是一个 Promise 实例,不管异步操作成功与否都会返回。
当你需要明确地知道每个 Promise 的状态并打印相关信息时,建议使用 Promise.allSettled。如果你只对成功的结果感兴趣,并可以忽略错误的情况,那么使用 Promise.all 是个不错的选择。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64ee9828f6b2d6eab388e7a1