ES11 的 Promise.any() 方法,解决 Promise.race() 的弊端

在 Web 前端开发中,异步编程方式已经成为了日常开发中的必备技能。Promise 是实现异步编程最常用的一种方式。ES6 引入了 Promise,ES10 对其进行了增强,新添加了 Promise.allSettled() 方法。而在 ES11 中,Promise.any() 方法被正式加入到了 Promise API 中,它解决了 Promise.race() 的一些弊端,让异步编程更加强大和灵活。

Promise.race() 的问题

Promise.race() 方法可以接收一组 Promise 实例,只要其中有一个 Promise 对象状态发生改变(不管是 resolve 还是 reject),最终返回的 Promise 对象的状态就会跟着改变。有利有弊,这种方式是非常高效和强大的,但是它有一个缺陷,就是仅仅返回最先被解决的 Promise 对象的结果,而忽略了其他未被解决的 Promise 实例的信息。

例如,下面的代码中同时发起两个请求,其中一个请求成功,另一个请求失败:

运行上述代码,我们发现控制台输出的信息只有 "Promise 1 resolved",没有任何关于 Promise 2 的信息。这是因为 Promise.race() 方法只关心第一个被解决的 Promise 对象。如果我们希望同时拿到多个 Promise 实例的结果,Promise.race() 就无法帮忙了。

Promise.any() 方法的优势

Promise.any() 方法在解决 Promise.race() 的问题上,提供了更加灵活和全面的解决方案。Promise.any() 方法同样接收一组 Promise 实例,但是只有当所有的 Promise 全部 reject 才会返回 reject,而如果其中任一 Promise resolve,则会返回 resolve。

下面是同样的两个 Promise 实例,但是这次使用 Promise.any():

在这个例子中,由于 Promise 1 在 Promise 2 之前解决,故返回 "Promise 1 resolved" 的信息。

另外,如果所有 Promise 实例均 reject,会返回 AggregateError 对象。我们可以通过捕获此错误对象并打印其错误信息,从而确保全部错误信息被捕获。

下面的例子同时发起两个请求,其中一个请求成功,另一个请求失败:

控制台输出的信息是:

由于 Promise 1 最先被解决,所以最终返回的是 Promise 1 的 resolve 的信息。

而如果我们将 Promise 2 的时间延长到 4000 ms,那么控制台输出的信息是:

这是因为在延长时间后,两个 Promise 都被 reject 了,所以最终返回的是一个 AggregateError 对象,打印了所有的错误信息。

如何使用 Promise.any()

Promise.any() 对于简化异步编程和提高代码可读性都是非常有帮助的。我们可以通过下面的代码进行简单的实验:

在浏览器环境下,我们通过 fetch 方法构造两个请求,一个是有效的请求,一个是非法的请求。使用 Promise.any() 方法进行解决的结果是:

由于第一个请求是有效的,所以成功返回结果。

在 Node.js 环境下我们通过下面的代码进行测试:

在 Node.js 环境下读取两个文件,一个是不存在的文件,一个存在的文件。使用 Promise.any() 方法进行解决的结果是:

由于第二个文件存在,成功返回文件二的内容。

总结

Promise 一直是异步编程的最重要工具之一,ES11 引入的 Promise.any() 方法解决了 Promise.race() 的一些问题,提供了更加全面和灵活的异步编程解决方案。开发者可以充分利用这个方法来编写更加健壮和可读性更好的代码。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65392a2c7d4982a6eb26e6b2


纠错
反馈