Promise.any()

Promise.any() 静态方法采用可迭代的 Promise 作为输入并返回单个 Promise。当任何输入的承诺履行时,返回的承诺就会履行,并具有第一个履行值。当所有输入的 Promise 都拒绝时(包括传递空迭代时),它会拒绝,并且 AggregateError 包含拒绝原因数组。

¥The Promise.any() static method takes an iterable of promises as input and returns a single Promise. This returned promise fulfills when any of the input's promises fulfills, with this first fulfillment value. It rejects when all of the input's promises reject (including when an empty iterable is passed), with an AggregateError containing an array of rejection reasons.

Try it

语法

¥Syntax

js
Promise.any(iterable)

参数

¥Parameters

iterable

iterable(例如 Array)的 Promise。

返回值

¥Return value

Promise 是:

¥A Promise that is:

  • 已经拒绝了,如果传过来的 iterable 是空的。
  • 当给定 iterable 中的任何承诺履行时,异步履行。履行值是第一个已履行的承诺的履行值。
  • 当给定 iterable 中的所有 Promise 都被拒绝时,异步被拒绝。拒绝原因是 AggregateError,其 errors 属性中包含一系列拒绝原因。错误按照传递的 Promise 的顺序排列,无论完成顺序如何。如果传递的 iterable 非空但不包含待处理的 Promise,则返回的 Promise 仍会被异步(而不是同步)拒绝。

描述

¥Description

Promise.any() 方法是 承诺并发 方法之一。此方法对于返回第一个履行的承诺很有用。它在一个承诺履行后会短路,因此一旦找到一个承诺,它就不会等待其他承诺完成。

¥The Promise.any() method is one of the promise concurrency methods. This method is useful for returning the first promise that fulfills. It short-circuits after a promise fulfills, so it does not wait for the other promises to complete once it finds one.

与返回一组履行值的 Promise.all() 不同,我们只获得一个履行值(假设至少有一个承诺履行)。如果我们只需要履行一个承诺,但我们并不关心是哪一个承诺,那么这可能是有益的。请注意另一个区别:此方法在收到空的可迭代对象时会拒绝,因为实际上该可迭代对象不包含满足条件的项目。你可以将 Promise.any()Promise.all()Array.prototype.some()Array.prototype.every() 进行比较。

¥Unlike Promise.all(), which returns an array of fulfillment values, we only get one fulfillment value (assuming at least one promise fulfills). This can be beneficial if we need only one promise to fulfill but we do not care which one does. Note another difference: this method rejects upon receiving an empty iterable, since, truthfully, the iterable contains no items that fulfill. You may compare Promise.any() and Promise.all() with Array.prototype.some() and Array.prototype.every().

此外,与返回第一个结算值(履行或拒绝)的 Promise.race() 不同,此方法返回第一个履行值。此方法会忽略所有被拒绝的承诺,直到第一个承诺履行为止。

¥Also, unlike Promise.race(), which returns the first settled value (either fulfillment or rejection), this method returns the first fulfilled value. This method ignores all rejected promises up until the first promise that fulfills.

示例

¥Examples

使用 Promise.any()

¥Using Promise.any()

Promise.any() 按照第一个要履行的承诺履行,即使承诺首先拒绝。这与 Promise.race() 形成鲜明对比,Promise.race() 是通过第一个承诺来实现或拒绝的。

¥Promise.any() fulfills with the first promise to fulfill, even if a promise rejects first. This is in contrast to Promise.race(), which fulfills or rejects with the first promise to settle.

js
const pErr = new Promise((resolve, reject) => {
  reject("Always fails");
});

const pSlow = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "Done eventually");
});

const pFast = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "Done quick");
});

Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
  // pFast fulfills first
});
// Logs:
// Done quick

因 AggregateError 拒绝

¥Rejections with AggregateError

如果没有兑现承诺,Promise.any() 将拒绝并发送 AggregateError

¥Promise.any() rejects with an AggregateError if no promise fulfills.

js
const failure = new Promise((resolve, reject) => {
  reject("Always fails");
});

Promise.any([failure]).catch((err) => {
  console.log(err);
});
// AggregateError: No Promise in Promise.any was resolved

显示加载的第一张图片

¥Displaying the first image loaded

在此示例中,我们有一个获取图片并返回 blob 的函数。我们使用 Promise.any() 来获取几个图片并显示第一个可用的图片(即其承诺已解决)。

¥In this example, we have a function that fetches an image and returns a blob. We use Promise.any() to fetch a couple of images and display the first one available (i.e. whose promise has resolved).

js
async function fetchAndDecode(url, description) {
  const res = await fetch(url);
  if (!res.ok) {
    throw new Error(`HTTP error! status: ${res.status}`);
  }
  const data = await res.blob();
  return [data, description];
}

const coffee = fetchAndDecode("coffee.jpg", "Coffee");
const tea = fetchAndDecode("tea.jpg", "Tea");

Promise.any([coffee, tea])
  .then(([blob, description]) => {
    const objectURL = URL.createObjectURL(blob);
    const image = document.createElement("img");
    image.src = objectURL;
    image.alt = description;
    document.body.appendChild(image);
  })
  .catch((e) => {
    console.error(e);
  });

规范

Specification
ECMAScript Language Specification
# sec-promise.any

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看