干掉 Promise.all!掌握Promise并发处理技巧!

大家在写 JavaScript 的时候,经常会用到各种 Promise 的各种静态方法,比如 Promise.allPromise.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.anyES2021 引入的一个用于处理多个 Promise 实例的新方法。它的作用是返回第一个 成功 的 Promise 结果,而忽略所有失败的 Promise。只有当所有 Promise 都失败时,才会抛出一个 AggregateError 错误。

在这里插入图片描述

在以上示例中,根据定时器的设置,getDataApi3 返回的 Promise 是最快完成并且处于成功状态的。因此,Promise.any 会优先处理该 Promise,并在控制台输出其成功结果。



5. 总结

本文详细介绍了 JavaScript 中的 Promise 并发处理方法,包括 Promise.all 的局限性、Promise.allSettled 的全面性、Promise.race 的竞争性以及 Promise.any 的择优性,并通过代码示例演示了它们的具体应用与区别。

如果觉得本文对你有帮助,希望能够给我点赞支持一下哦 💪 也可以关注wx公众号:程序员付杰 ,一起学习编程技能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员付杰

欢迎投喂, 一起共享知识的盛宴

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值