写点什么

Promise.allSettled 的 Polyfill 处理

作者:Jerry Wang
  • 2022 年 8 月 18 日
    四川
  • 本文字数:1361 字

    阅读完需:约 4 分钟

Promise.allSettled 的 Polyfill 处理

如果因为浏览器太过老旧,不支持最新的 Promise.allSettled API,我们可以使用 polyfill 技术,简单地自己用 Promise.all, 自行实现 Promise.allSettled.


完整代码实现如下:


if (!Promise.allSettled) {  const rejectHandler = reason => ({ status: 'rejected', reason });
const resolveHandler = value => ({ status: 'fulfilled', value });
Promise.allSettled = function (promises) { const convertedPromises = promises.map(p => Promise.resolve(p).then(resolveHandler, rejectHandler)); return Promise.all(convertedPromises); };}
复制代码


在这段代码中,promises.map 接受输入值,使用 p => Promise.resolve(p) 将它们转换为 Promise(以防传递了非 Promise 类型的 primitive 值),然后将 .then 处理程序添加到每个值。


该处理程序将成功的结果值转换为 {status:'fulfilled', value},并将错误原因转换为 {status:'rejected', reason}。 这正是 Promise.allSettled 的格式。


现在我们可以使用 Promise.allSettled 来获取所有给定 Promise 的结果,即使其中一些被 reject.

Promise.race

与 Promise.all 类似,但仅等待第一个已经 resolved 的 Promise 并获取其结果(或错误)。


语法:


let promise = Promise.race(iterable);
复制代码


下列代码将会打印第一个状态变为 fulfilled 的 Promise 的值,即 1:


Promise.race([  new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Whoops!")), 2000)),  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))]).then(alert); // 1
复制代码


这里的第一个 promise 是最快的,所以就变成了结果。 在第一个确定的 Promise win the race之后,所有进一步的结果/错误都将被忽略。

Promise.any

与 Promise.race 类似,但只等待第一个 fulfilled 的 Promise 并获得其结果。 如果所有给定的 Promise 都被拒绝,则返回的 Promise 会被 AggregateError 拒绝——这是一个特殊的错误对象,它将所有 Promise 错误存储在它的 errors 属性中。


语法:


let promise = Promise.any(iterable);
复制代码


下列例子结果为 1:


Promise.any([  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Whoops!")), 1000)),  new Promise((resolve, reject) => setTimeout(() => resolve(1), 2000)),  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))]).then(alert); // 1
复制代码


这里的第一个 promise 是最快的,但是被 reject 了,所以第二个 promise 就变成了结果。 在第一个 fulfilled 的 Promise win the race 之后,所有进一步的结果都将被忽略。


这是一个所有 Promise 都失败的例子:


Promise.any([  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Ouch!")), 1000)),  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Error!")), 2000))]).catch(error => {  console.log(error.constructor.name); // AggregateError  console.log(error.errors[0]); // Error: Ouch!  console.log(error.errors[1]); // Error: Error!});
复制代码


如我们所见,失败的 Promise 的错误对象在 AggregateError 对象的 errors 属性中可用。

发布于: 刚刚阅读数: 3
用户头像

Jerry Wang

关注

🏆InfoQ写作平台-签约作者🏆 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。2007 年从电子科技大学计算机专业硕士毕业后加入 SAP 成都研究院工作至今。工作中使用 ABAP, Java, JavaScript 和 TypeScript 进行开发。

评论

发布
暂无评论
Promise.allSettled 的 Polyfill 处理_JavaScript_Jerry Wang_InfoQ写作社区