自 ES6 开始,Promise 就成为了异步编程中的重要工具,它可以帮助开发者优雅地解决回调地狱问题;同时,Promise 在之后的版本中也不断有新的 API 的增加,以满足不断升级的需求。
在 ES11 中,Promise.allSettled 方法是新加入的一个 API,它是 Promise.all 方法的升级版,可以让开发者更加灵活地处理异步操作的情况。
Promise.all 方法的缺陷
在 ES6 中,Promise.all 方法可以接收一组 Promise 对象,返回一个 Promise 对象,只有所有 Promise 对象都 resolved 或者其中一个 Promise 对象 rejected 才会结束。
然而,Promise.all 在增加并发量时可能会出现问题。例如,在对多个外部 API 进行请求时,如果其中一个出现问题就会导致整个 Promise.all 出现问题,无法获取其他 API 的结果。
Promise.allSettled 方法的介绍
Promise.allSettled 解决了 Promise.all 在出现错误时无法返回其他 Promise 结果的问题。它返回一个由 Promise 对象组成的数组,每个 Promise 对象都包含了对应的结果信息。在所有 Promise 都处理完成后,该方法返回的 Promise 对象才会 resolve,而不管每个 Promise 是否成功。
Promise.allSettled 接收一组 Promise 对象,并且返回一个 Promise 对象。这个 Promise 对象总是 resolve,并提供一个所有 Promise 对象集合的结果数组。
Promise.allSettled 方法的语法
Promise.allSettled(iterable)
参数
可迭代的 Promise 对象集合。
返回值
一个新的 Promise 对象。
Promise.allSettled 方法的使用技巧
方案一:串行处理
在某些情况下,我们需要对多个异步操作进行串行处理,例如:每个异步操作依赖上一个异步操作的结果。使用 Promise.allSettled 可以很方便地帮助我们进行处理,如下面的示例:
async function serialAsyncMap(tasks) { const results = []; for (const task of tasks) { const result = await task(); results.push(result); } return results; } const promises = [ () => Promise.resolve('a'), () => Promise.resolve('b'), () => Promise.reject('c'), ]; serialAsyncMap(promises.map(p => p.catch(e => e))) .then(results => console.log(results));
在这个示例中,我们定义了一个名为 serialAsyncMap 的函数,该函数可以按照传入的异步操作序列依次执行这些操作。在主函数中,定义了一个包含 3 个 Promise 对象的数组,分别代表操作 a、操作 b 和操作 c。
然后,我们通过 map 方法对数组进行了转换,将所有的 Promise 对象都通过 catch 方法转换为 resolve 状态。这是为了保证对于任何一个 Promise 对象,Promise.allSettled 都可以处理这个 Promise 对象,并将结果传递下去。
最后,我们调用 serialAsyncMap 函数来串行处理这些异步任务,并打印输出结果。
方案二:返回并发结果
在某些情况下,我们需要对一个异步操作基于并发的方式进行处理,例如:每个异步操作不依赖上一个异步操作的结果。使用 Promise.allSettled 可以让我们强制返回 Promise 对象的结果集合,并且而不管其是否成功,如下面的示例:
const promises = [ () => Promise.resolve('a'), () => Promise.resolve('b'), () => Promise.reject('c'), ]; Promise.allSettled(promises.map(p => p())) .then(results => console.log(results));
在这个示例中,通过 Promise.allSettled 方法对所有 Promise 对象进行处理,并且可以获取具有多个异步操作的异步结果。
总结
本文介绍了 ES11 中新增的 Promise.allSettled 方法的基本用法,并且通过示例演示了如何利用其优雅地处理并发和串行任务集合。
利用 Promise.allSettled,我们可以写出更简洁、可维护、可读的代码,同时降低开发过程中出现的意外情况的概率。因此,在项目开发过程中,我们应该熟练掌握 Promise.allSettled 的使用技巧,并且在适合的时候应用它来帮助我们解决问题。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659ec658add4f0e0ff7975e3