在前端开发中,经常会遇到需要并发请求多个异步操作的情况。在 ES6 中,我们可以使用 Promise.all 方法来实现并发请求,并在所有请求执行完毕后获得结果。但是如果其中一个请求发生错误,整个 Promise 都会被 reject。这是一个问题,因为我们希望得到的结果是其中任一个异步操作的结果,并不需要等待所有异步操作都完成。这是 ES12 中引入的 Promise.any 方法就派上了用场。
Promise.any 方法
Promise.any 方法可以接受一组 Promise 对象,并返回其中任意一个 Promise 的结果。如果其中所有的 Promise 都被 reject,那么 Promise.any 会返回一个 AggregateError 类型的错误。AggregateError 是 ES12 新引入的一个错误类型,它可以包含一个数组,数组中每个元素代表一个错误。
Promise.any([Promise.resolve(1), Promise.reject(2), Promise.resolve(3)]) .then((value) => console.log(value)) .catch((err) => console.log(err)); // 输出 1
在这个例子中,Promise.resolve(1) 和 Promise.resolve(3) 都是成功的,而 Promise.reject(2) 是失败的。由于 Promise.any 方法只需要其中任意一个成功,所以返回的结果是 1。
当所有的 Promise 都失败时,Promise.any 将会返回一个 AggregateError 类型的错误,其中每个元素是一个 Promise 的错误信息。
Promise.any([Promise.reject(1), Promise.reject(2), Promise.reject(3)]) .then((value) => console.log(value)) .catch((err) => console.log(err)); // 输出 AggregateError: [Error: 1, Error: 2, Error: 3]
Promise.any 方法的作用
Promise.any 方法可以简化异步操作的组装过程,使开发者更加方便地使用并发请求的方式。比如,我们可以使用 Promise.any 方法在页面加载时并发请求多个资源,只需要获取其中一个资源的结果就可以开始显示页面。
Promise.any([ fetch('/api/data1'), fetch('/api/data2'), fetch('/api/data3'), fetch('/api/data4'), ]).then((value) => console.log(value));
当我们需要从多个 API 中获取结果,但并不关心哪个 API 首先返回结果时,Promise.any 方法可以提供便利的解决方案。
Promise.any 方法的注意事项
值得注意的是,Promise.any 方法是 ES12 中引入的,因此在使用时需要先检查浏览器是否支持该方法。当浏览器不支持 Promise.any 方法时,可以使用 Promise.race 方法代替,它们的区别在于 Promise.race 会等待任意一个 Promise 被解决,而 Promise.any 只会等待其中任何一个 Promise 被解决。
Promise.any = Promise.any || function(promises) { return Promise.race(promises.map(p => Promise.resolve(p).then(value => Promise.reject(value), err => Promise.resolve(err)))); };
结论
在并发异步操作时,Promise.any 方法可以让开发者更加方便地使用并发请求的方式,减少开发时间与工作量。同时,了解 Promise.any 方法的限制和使用场景,可以让我们在开发中更加灵活地使用 ES6 已经 ES12 中的 Promise 方法。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67073137d91dce0dc865b1ea