参考答案:
一句话概括Promise.allSettled
和Promise.all
的最大不同:Promise.allSettled
永远不会被reject。
当需要处理多个Promise并行时,大多数情况下Promise.all用起来是非常顺手的,比如下面这样
1const delay = n => new Promise(resolve => setTimeout(resolve, n)); 2 3const promises = [ 4 delay(100).then(() => 1), 5 delay(200).then(() => 2), 6 ] 7 8Promise.all(promises).then(values=>console.log(values)) 9// 最终输出: [1, 2]
可是,是一旦有一个promise出现了异常,被reject了,情况就会变的麻烦。
1const promises = [ 2 delay(100).then(() => 1), 3 delay(200).then(() => 2), 4 Promise.reject(3) 5 ] 6 7Promise.all(promises).then(values=>console.log(values)) 8// 最终输出: Uncaught (in promise) 3 9 10Promise.all(promises) 11.then(values=>console.log(values)) 12.catch(err=>console.log(err)) 13// 加入catch语句后,最终输出:3
尽管能用catch捕获其中的异常,但你会发现其他执行成功的Promise的消息都丢失了,仿佛石沉大海一般。
要么全部成功,要么全部重来,这是Promise.all本身的强硬逻辑,也是痛点的来源,不能说它错,但这的确给Promise.allSettled留下了立足的空间。
假如使用Promise.allSettled来处理这段逻辑会怎样呢?
1const promises = [ 2 delay(100).then(() => 1), 3 delay(200).then(() => 2), 4 Promise.reject(3) 5 ] 6 7Promise.allSettled(promises).then(values=>console.log(values)) 8// 最终输出: 9// [ 10// {status: "fulfilled", value: 1}, 11// {status: "fulfilled", value: 2}, 12// {status: "rejected", value: 3}, 13// ]
可以看到所有promise的数据都被包含在then语句中,且每个promise的返回值多了一个status字段,表示当前promise的状态,没有任何一个promise的信息被丢失。
因此,当用Promise.allSettled时,我们只需专注在then语句里,当有promise被异常打断时,我们依然能妥善处理那些已经成功了的promise,不必全部重来。
最近更新时间:2024-08-10