myfreax

JavaScript Promise.any() 静态方法

您将学习如何使用 JavaScript Promise.any() 方法来聚合 Promise

JavaScript Promise.any() 静态方法
JavaScript Promise.any() 静态方法

在本教程中,您将学习如何使用 JavaScript Promise.any() 方法来编写 Promise。

JavaScript Promise.any() 方法介绍

Promise.any()  静态方法接受一个 Promise 可迭代对象列表参数:

Promise.any(iterable);

如果可迭代对象中的 Promise 之一得到解决,则 Promise.any() 返回一个 Promise,此 Promise 解析为一个值,此值是已解决的 Promise 的结果:

在此图中:

  • promise1t1 时返回 v1 值并解决。
  • promise2t2 时返回 v2 值并解决。
  • Promise.any() 返回一个解析为 v1 值的 Promise,该值是 promise1 的结果

即使 Promise.any() 可迭代对象中的某些 Promise 被拒绝,它也会返回一个 Promise ,该 Promise 的值来自第一个得满足的 Promise:

在此图中:

  • promise1t1 时因 error 被拒绝。
  • promise2t2 时返回 v2 的值得到满足。
  • Promise.any() 返回一个 Promise ,该 Promise 会返回值 v2 ,它是 promise2 的结果。请注意,Promise.any() 方法忽略被拒绝的承诺 。

如果可迭代对象中的所有承诺都被拒绝或者可迭代对象为空,则 Promise.any() 返回一个拒绝的承诺,其中 AggregateError 包含所有拒绝原因。AggregateErrorError 的子类。

在此图中:

  • promise1t1 时因 error1 被拒绝。
  • promise2t2 时因 error2 被拒绝。
  • Promise.any() 返回一个被拒绝的承诺,其中 AggregateError 包含所有被拒绝的 promise 的 error1error2

JavaScript Promise.any() 示例

让我们举一些使用 Promise.any() 方法的例子。

所有 Promise 都解决的例子

下面示例展示 Promise.any() 已解决所有 Promise 的方法:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 1 fulfilled');
    resolve(1);
  }, 1000);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 2 fulfilled');
    resolve(2);
  }, 2000);
});

const p = Promise.any([p1, p2]);
p.then((value) => {
  console.log('Returned Promise');
  console.log(value);
});

输出:

Promise 1 fulfilled
Returned Promise
1
Promise 2 fulfilled
  • 首先,创建一个新的 promise p1,它将在一秒钟后解析为一个值 1
  • 其次,创建一个新的 promise p2,它将在两秒后解析为一个值 2
  • 第三,使用Promise.any()使用两个 promisep1和 的方法p2Promise.any() 返回一个 promise p,该 promise 将在一秒后解析为第一个已实现的 promise ( p1 ) 的值 1

一个 promise 被拒绝的例子

下面示例展示使用 Promise.any() 具有拒绝 Pormise 的方法:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 1 rejected');
    reject('error');
  }, 1000);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 2 fulfilled');
    resolve(2);
  }, 2000);
});

const p = Promise.any([p1, p2]);
p.then((value) => {
  console.log('Returned Promise');
  console.log(value);
});

输出:

Promise 1 rejected
Promise 2 fulfilled
Returned Promise
2

在此示例中,Promise.any() 忽略被拒绝的承诺。当 p2 以值 2 解决时,Promise.any() 返回一个 Promise ,该 Promise 解析为与 p2 的结果相同的值。

所有 Promise 被拒绝的例子

下面示例展示 Promise.any() 在拒绝所有 Promise 的情况:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 1 rejected');
    reject('error1');
  }, 1000);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 2 rejected');
    reject('error2');
  }, 2000);
});

const p = Promise.any([p1, p2]);
p.catch((e) => {
  console.log('Returned Promise');
  console.log(e, e.errors);
});

输出:

Promise 1 rejected
Promise 2 rejected
Returned Promise
[AggregateError: All promises were rejected] [ 'error1', 'error2' ]

在此示例中,p1  和 p2 均被 error1error2 拒绝。因此,Promise.any() 方法被一个 AggregateError 对象拒绝,AggregateError 对象的 errors 属性包含被拒绝 promise 的所有错误。

何时使用 JavaScript Promise.any() 方法

实际上,您使用 Promise.any() 返回第一个解决的 Promise。一旦一个 promise 被解决,Promise.any() 方法就不会等待其他 promise 完成。

例如,您有一个资源由两个或多个内容分发网络 CDN 提供服务。要动态加载第一个可用资源,您可以使用 Promise.any() 方法。

下面的示例展示如何使用 Promise.any() 方法获取两个张图片并显示第一个可用图片。

index.html 文件

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>JavaScript Promise.any() Demo</title>
    </head>
    <body>
        <script src="js/app.js"></script>
    </body>
</html>

app.js 文件

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

let cat = getImageBlob(
  'https://upload.wikimedia.org/wikipedia/commons/4/43/Siberian_black_tabby_blotched_cat_03.jpg'
);
let dog = getImageBlob(
  'https://upload.wikimedia.org/wikipedia/commons/a/af/Golden_retriever_eating_pigs_foot.jpg'
);

Promise.any([cat, dog])
  .then((data) => {
    let objectURL = URL.createObjectURL(data);
    let image = document.createElement('img');
    image.src = objectURL;
    document.body.appendChild(image);
  })
  .catch((e) => {
    console.log(e.message);
  });
  • 首先,定义 getImageBlob() 使用 fetch API 从 URL 获取图像 blob的函数。getImageBlob() 返回 Promise ,该 Promise 的值是图像的 blob 对象。
  • 其次,定义两个加载图像的 Promise
  • 最后,使用 Promise.any() 方法显示第一个可用图像。

结论

  • 使用 JavaScript Promise.any() 方法获取 Promise 列表并返回首先实现的Promise

内容导航