在前端开发中,我们经常会使用 Promise 来进行异步编程。而在多个异步任务需要同时完成时,我们会使用 Promise.all 来等待所有任务完成后再进行下一步操作。不过,当其中一个异步任务出错时,Promise.all 会直接返回该任务的错误结果,而不是等待其他任务完成后再返回错误结果。这种情况下,我们经常会遇到错误结果不是我们期望的情况。
问题分析
Promise.all 接收一个 promise 的数组,它会在所有 promise 都成功的情况下,以一个包含所有 promise 结果的数组形式返回。而如果其中一个 promise 出错,它会直接返回出错的结果。这种结果常常会导致问题:当有多个 promise 出现错误时,我们只能得到其中一个的错误结果,其他错误结果会丢失。同时,返回结果的顺序也是不可控的,有可能返回的是数组中最后一个 promise 的结果。
解决方式
为了避免这种情况,我们可以使用 Promise.allSettled 取代 Promise.all。Promise.allSettled 会等待所有 promise 完成,不管它们是否出错,并将所有 promise 的状态(成功或失败)以及对应的结果打包成一个数组返回。这样,我们就可以得到所有 promise 的结果,无论成功或失败。
下面是一个使用 Promise.allSettled 的例子:
const promises = [Promise.resolve(1), Promise.reject('oops'), Promise.resolve(3)]; Promise.allSettled(promises) .then(results => results.forEach(result => console.log(result.status, result.value))) .catch(error => console.error(error));
输出:
"fulfilled" 1 "rejected" "oops" "fulfilled" 3
如上所述,Promise.allSettled 对错误也进行了处理,这意味着你无需设置 catch 来捕获错误。此外,我们可以很容易地从打包的结果中获取值和状态。例如,我们可以使用 filter 将所有成功和失败的结果分别存储到不同的数组中:
-- -------------------- ---- ------- ----- -------- - -------------------- ----------------------- -------------------- ---------------------------- ------------- -- - ----- --------- - --------------------- -- ------------- --- ------------- ----- -------- - --------------------- -- ------------- --- ------------ ----------------------- ---------------------- -- ----------------- ---------------------- --------------------- -- ------------------ ---
输出:
fulfilled: 1,3 rejected: oops
总结
在异步编程中使用 Promise.all 是非常常见的,但当有错误发生时,它有可能会导致我们忽略了其他结果。为此,Promise.allSettled 是更好的替代方案,它会将所有 promise 的结果以及状态打包成一个数组返回。值得注意的是,在使用 Promise.allSettled 时,我们不需要再设置 catch 来捕获错误。
以上就是解决 Promise.all 执行错误时返回的是数组中的最后一个结果的一些方法,希望本文能够帮助读者更好地理解 Promise.allSettled 的作用以及如何使用它。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649cd6eb48841e9894987730