文章目录
大家在写 JavaScript 的时候,经常会用到各种 Promise 的各种静态方法,比如 Promise.all、Promise.allSettled、Promise.race、Promise.any 等等。这些方法确实很强大。今天,我们就来聊聊这些 Promise 的操作。
1. Promise.all
1.1. 基本用法与局限性
长期以来,Promise.all() 一直是我们处理并发 Promise 的首选方法。其使用如下

但它存在一个致命缺陷:一旦参数中任何一个 Promise 被拒绝(rejected),整个操作就会失败。

1.2. 处理Promise.all 局限性问题
其实,Promise.all() 的问题并不复杂,只要你抓住原理,就有办法轻松解决。通过前面的介绍,我们知道 Promise.all() 只能处理 所有 Promise 都成功 的情况。但如果其中一个 Promise 失败了,整个 Promise.all() 就会失败,这显然不符合某些场景的需求。
那么,问题来了:如果碰到 reject 的情况,我们该怎么办呢?其实很简单!我们只需要 给每个 Promise 绑定一个自己的 catch 方法。如果某个 Promise失败了(即进入 reject 状态),它会调用自己的 catch 回调函数。而且,根据 Promise 的链式处理原则,catch 回调返回的内容默认是 resolve 状态。这样一来,即使某个任务失败了,Promise.all() 也不会直接崩掉,而是会继续执行其他任务,并返回所有任务的结果。
修改上面的示例代码:

在这段代码中,即使第一个请求失败了,它也会返回一个包含错误信息的对象。而 Promise.all() 会继续执行其他任务,最终返回一个完整的结果数组。这样一来,我们既不会中断任务的执行,又能清晰地知道哪些任务失败了。
2. Promise.allSettled
Promise.allSettled() 是在 ECMAScript 2020(ES11) 中正式引入的。专门用来处理多个 Promise 的并发执行,并且会等待所有 Promise 完成(无论是 fulfilled 还是 rejected),然后返回一个描述每个 Promise 结果的对象数组。具有以下结构:
- 对于成功的 Promise:{ status: ‘fulfilled’, value: 结果值 }
- 对于失败的 Promise:{ status: ‘rejected’, reason: 错误原因 }

在当前示例中, Promise.allSettled对应不同状态放回的不同的字段以及添加状态标记成功或失败。 这就修复了Promise.all()整体失败后获取不到其中成功状态的Promise 数据问题.
3. Promise.race
Promise.race是 JavaScript 中用于处理多个 Promise 并发执行的实用方法。它的核心思想是“赛跑”:它会同时执行多个 Promise,但只关心谁先完成(无论是成功还是失败),并立即返回这个最快的 Promise 的结果。其他 Promise 的结果会被忽略。

在当前示例中,由于 promise2 最先完成并返回成功状态,Promise.race 会立即“锁定”它的结果,并触发其 then 回调函数进行处理。其他 Promise 的结果,无论成功与否,都会被直接忽略。
如果此时我们将 promise2 修改为 reject 失败状态,Promise.race 仍然会优先处理这个最快的 Promise,但由于其状态为失败,最终会执行 catch 回调函数来捕获错误。
4. Promise.any
Promise.any 是 ES2021 引入的一个用于处理多个 Promise 实例的新方法。它的作用是返回第一个 成功 的 Promise 结果,而忽略所有失败的 Promise。只有当所有 Promise 都失败时,才会抛出一个 AggregateError 错误。

在以上示例中,根据定时器的设置,getDataApi3 返回的 Promise 是最快完成并且处于成功状态的。因此,Promise.any 会优先处理该 Promise,并在控制台输出其成功结果。
5. 总结
本文详细介绍了 JavaScript 中的 Promise 并发处理方法,包括 Promise.all 的局限性、Promise.allSettled 的全面性、Promise.race 的竞争性以及 Promise.any 的择优性,并通过代码示例演示了它们的具体应用与区别。
如果觉得本文对你有帮助,希望能够给我点赞支持一下哦 💪 也可以关注wx公众号:
程序员付杰,一起学习编程技能

6206

被折叠的 条评论
为什么被折叠?



