共计 2115 个字符,预计需要花费 6 分钟才能阅读完成。
不论你是否还学的动,JS 语言仍然在以本人的节奏飞快的进化。转眼间,Promise 的工具包里又多了一个办法 Promise.allSettled 供你抉择,它看起来像是对 Promise.all 的一种补充,缓解了应用 Promise.all 碰到 reject 的痛点问题。
一句话概括 Promise.allSettled 和 Promise.all 的最大不同:Promise.allSettled 永远不会被 reject。
解决 Promise.all 的痛点
当须要解决多个 Promise 并行时,大多数状况下 Promise.all 用起来是十分棘手的,比方上面这样
const delay = n => new Promise(resolve => setTimeout(resolve, n));
const promises = [delay(100).then(() => 1),
delay(200).then(() => 2),
]
Promise.all(promises).then(values=>console.log(values))
// 最终输入:[1, 2]
可是,是一旦有一个 promise 呈现了异样,被 reject 了,状况就会变的麻烦。
const promises = [delay(100).then(() => 1),
delay(200).then(() => 2),
Promise.reject(3)
]
Promise.all(promises).then(values=>console.log(values))
// 最终输入:Uncaught (in promise) 3
Promise.all(promises)
.then(values=>console.log(values))
.catch(err=>console.log(err))
// 退出 catch 语句后,最终输入:3
只管能用 catch 捕捉其中的异样,但你会发现其余执行胜利的 Promise 的音讯都失落了,好像杳无音信个别。
要么全副胜利,要么全部重来,这是 Promise.all 自身的强硬逻辑,也是痛点的起源,不能说它错,但这确实给 Promise.allSettled 留下了立足的空间。
如果应用 Promise.allSettled 来解决这段逻辑会怎么呢?
const promises = [delay(100).then(() => 1),
delay(200).then(() => 2),
Promise.reject(3)
]
Promise.allSettled(promises).then(values=>console.log(values))
// 最终输入:// [// {status: "fulfilled", value: 1},
// {status: "fulfilled", value: 2},
// {status: "rejected", value: 3},
// ]
能够看到所有 promise 的数据都被蕴含在 then 语句中,且每个 promise 的返回值多了一个 status 字段,示意以后 promise 的状态,没有任何一个 promise 的信息被失落。
因而,当用 Promise.allSettled 时,咱们只需专一在 then 语句里,当有 promise 被异样打断时,咱们仍然能妥善处理那些曾经胜利了的 promise,不用全部重来。
以后大环境对 Promise.allSettled 的反对
nodejs 从 v12.9.0 开始退出了对 Promise.allSettled 的反对,支流浏览器们也各自在 2019 年公布的版本中反对了此办法,这意味着你曾经能够放心大胆的应用了。
对于那些不反对此办法的环境,你能够间接援用开源社区中实现了此办法的 npm 包:
- promise.allsettled
- promise-settle
- promise-all-settled
- es2015-promise.allsettled
或者,你能够间接基于 Promise.all 写一个 polyfill,给你的我的项目打上补丁:
if (Promise && !Promise.allSettled) {Promise.allSettled = function (promises) {return Promise.all(promises.map(function (promise) {return promise.then(function (value) {return { state: 'fulfilled', value: value};
}).catch(function (reason) {return { state: 'rejected', reason: reason};
});
}));
};
}
结语
Promise.allSettled 是对 Promise.all 的一种补充,当面对多个 promise 并行时,它额定提供了一种解决形式,解决了当多个 promise 并行时 reject 的呈现会随同着其余 promise 数据失落的问题。
参考资料
using-promise-allsettled-now
proposal-promise-allSettled
es2015-Promise.allSettled
nodejs v12.9.0 release notes