Promise.any() 是 ECMAScript 2021 中新增的方法之一,它的作用是在所有 Promise 中只要有一个 resolve 了,它就会 resolve;如果全部 reject 了,那它就会 reject。如果你对它并不是很熟悉,类似于以下这段代码:
Promise.any([Promise.reject(1), Promise.reject(2), Promise.resolve(3)]) .then((value) => { console.log(value); // 3 }) .catch((reason) => { console.log(reason); // AggregateError: All promises were rejected });
这段代码经过 promise.any 会输出 3,因为 Promise.resolve(3) resolve 了;如果 Promise.resolve(3) 换成 Promise.reject(3), 则所有 Promise 都会 reject 后输出一个 AggregateError 错误。
接下来,我们深入了解一下 Promise.any(),并学习如何在前端开发中更好地使用它。
Promise.any() 的基础知识
Promise.any() 拥有以下特点:
- 当传入的 Promise 有一个是 resolved 状态,Promise.any() 立即 resolve。
- 当传入的 Promise 全部都是 reject 状态,Promise.any() 会返回 AggregateError 错误。
- 和 Promise.race() 一样,Promise.any() 同样可以接受两个或者以上的 Promise。
- Promise.any() 返回的 Promise 的值是第一个被 fulfilled 的 Promise 的值。
- Promise.any() 返回的 Promise 的状态和第一个被 fulfilled 的 Promise 一致。
基本上,Promise.any() 与 Promise.race() 类似,只不过 Promise.any() 可以接受两个或以上的 Promise 对象,并且只要其中一个 Promise 对象有结果返回即可,而 Promise.race() 是只要有一个 Promise 对象有结果返回即可。
Promise.any() 的使用
在实际项目中,Promise.any() 可以帮助我们同时调用两个或者多个请求,并且只要有一个请求返回结果,就可以执行后续操作。
下面是一个具体的示例:
-- -------------------- ---- ------- ----- -------- --------------------- -------- - ----- ---------- - --- ------------------ ----- - ------ - - ----------- ----- --------- - ------------- -- ------------------- --------- ----- --- - ----- ---------- - ------ --- ------------------------ ------ ---- - --- - ---------- -- ----- -------- ------------------------ - ----- -------- - ----------------- -------- -- - --- - ----- --- - --------------------------------------------------------- ----- ------- - ----- --------------------- ------- ----- ------------ - ----- --------------- -- ---------------------- - ----- --------------------------------- - ------ ------------- - ----- --- - ------------------------------------------------- - --- ----- ------ - ----- ---------------------- ------ ------- -
在这个示例中,我们假设我们接口中返回的 userIds 是由后台人员提供的。那么我们就不知道在多少个请求中有结果返回,或者在多久之后。使用 Promise.any() 就可以方便地处理这种情况。
Promise.any() 的注意事项
虽然 Promise.any() 带来了方便,但它也有一些需要注意的地方,其中最重要的是:
- 当传入的 Promise 全部都是 reject 状态时,Promise.any() 会返回 AggregateError 错误。
- 如果使用 Promise.any() 的话,一定要加上对 AggregateError 的处理代码。
对于第一点,我们需要提前考虑。如果我们希望所有请求都失败才会出错,那么我们就尽量避免使用 Promise.any()。如果我们确定传入的 Promise 在全部 reject 时会出现错误,那么我们也需要加上对 AggregateError 的处理代码。
下面是处理 AggregateError 的方式:
const errors = []; Promise.any([Promise.reject(1), Promise.reject(2), Promise.reject(3)]) .catch((reason) => { errors.push(reason); if (errors.length === 3) { throw new Error(errors.map(error => error.message).join(',')) } });
当错误发生时,我们会将错误推入至一个数组中,当我们已经等待所有请求结束后,再抛出错误。
总结
Promise.any() 新增了一个方便的方式来处理多个异步操作并取回第一个成功的操作的结果。与之前的 Promise.all() 方法类似,这个方法也带来了一些注意点。对于使用 Promise.any() 的场景,需要对 AggregateError 错误的处理方式格外小心。当然,如何在实践中使用 Promise.any() 还是需要我们在开发中不断实践,发掘出更多的技巧和最佳的使用方式。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64912b1548841e9894f2f0b6