Promise.any()

Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise AggregateError类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()是相反的。

注意! Promise.any() 方法依然是实验性的,尚未被所有的浏览器完全支持。它当前处于 TC39 第四阶段草案(Stage 4)

语法

Promise.any(iterable);

参数

iterable
一个可迭代的对象, 例如 Array

返回值

  • 如果传入的参数是一个空的可迭代对象,则返回一个 已完成(already resolved) 状态的 Promise
  • 如果传入的参数不包含任何 promise,则返回一个 异步完成 (asynchronously resolved)的 Promise
  • 其他情况下都会返回一个处理中(pending) 的 Promise。 只要传入的迭代对象中的任何一个 promise 变成成功(resolve)状态,或者其中的所有的 promises 都失败,那么返回的 promise 就会 异步地(当调用栈为空时) 变成成功/失败(resolved/reject)状态。

说明

这个方法用于返回第一个成功的 promise 。只要有一个 promise 成功此方法就会终止,它不会等待其他的 promise 全部完成。

不像 Promise.all() 会返回一组完成值那样(resolved values),我们只能得到一个成功值(假设至少有一个 promise 完成)。当我们只需要一个 promise 成功,而不关心是哪一个成功时此方法很有用的。

同时, 也不像 Promise.race() 总是返回第一个结果值(resolved/reject)那样,这个方法返回的是第一个 成功的 值。这个方法将会忽略掉所有被拒绝的 promise,直到第一个 promise 成功。

成功(Fulfillment):

当任何一个被传入的 promise 成功的时候, 无论其他的 promises 成功还是失败,此函数会将那个成功的 promise 作为返回值 。

  • 如果传入的参数是一个空的可迭代对象, 这个方法将会同步返回一个已经完成的 promise
  • 如果传入的任何一个 promise 已成功, 或者传入的参数不包括任何 promise, 那么 Promise.any 返回一个异步成功的 promise

失败/拒绝(Rejection):

如果所有传入的 promises 都失败, Promise.any 将返回异步失败,和一个 AggregateError 对象,它继承自 Error,有一个 error 属性,属性值是由所有失败值填充的数组。

示例

First to fulfil

即使第一个返回的 promise 是失败的,Promise.any() 依然使用第一个成功状态的 promise 来返回。这与使用首个(无论 rejected 还是 fullfiled)promise 来返回的 Promise.race() 相反。

const pErr = new Promise((resolve, reject) => {
  reject("总是失败");
});

const pSlow = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "最终完成");
});

const pFast = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "很快完成");
});

Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
  // pFast fulfils first
})
// 期望输出: "很快完成"

Rejections with AggregateError

如果没有 fulfilled (成功的) promise,Promise.any() 返回 AggregateError 错误。

const pErr = new Promise((resolve, reject) => {
  reject('总是失败');
});

Promise.any([pErr]).catch((err) => {
  console.log(err);
})
// 期望输出: "AggregateError: No Promise in Promise.any was resolved"

显示第一张已加载的图片

在这个例子,我们有一个获取图片并返回 blob 的函数,我们使用 Promise.any() 来获取一些图片并显示第一张有效的图片(即最先 resolved 的那个 promise)。

function fetchAndDecode(url) {
  return fetch(url).then(response => {
    if(!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    } else {
      return response.blob();
    }
  })
}

let coffee = fetchAndDecode('coffee.jpg');
let tea = fetchAndDecode('tea.jpg');

Promise.any([coffee, tea]).then(value => {
  let objectURL = URL.createObjectURL(value);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
})
.catch(e => {
  console.log(e.message);
});

规范

规范
Promise.any

浏览器兼容性

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
anyChrome Full support 85Edge No support NoFirefox Full support 79IE No support NoOpera No support NoSafari Full support 14WebView Android Full support 85Chrome Android Full support 85Firefox Android No support NoOpera Android No support NoSafari iOS Full support 14Samsung Internet Android No support Nonodejs No support No

Legend

Full support  
Full support
No support  
No support

参见