乐趣区

关于前端:PromiseallSettled-的-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 属性中可用。

退出移动版