JavaScript Promise.any()

摘要:在本教程中,您将学习如何使用 JavaScript Promise.any() 方法来组合 Promise。

JavaScript Promise.any() 方法简介

Promise.any() 方法接受一个 Promise 对象列表作为 可迭代对象

Promise.any(iterable);Code language: JavaScript (javascript)

如果可迭代对象中的 Promise 之一已完成,则 Promise.any() 将返回一个单个 Promise,该 Promise 解析为一个值,该值是已完成 Promise 的结果。

在此图中

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

Promise.any() 返回一个 Promise,该 Promise 将使用第一个已完成的 Promise 完成,即使可迭代对象中的某些 Promise 失败了。

在此图中

  • promise1t1 时被 error 拒绝。
  • promise2t2 时被完成为值 v2
  • Promise.any() 返回的 Promise 解析为值 v2,即 promise2 的结果。请注意,Promise.any() 方法会忽略失败的 Promise (promise1)。

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

在此图中

  • promise1t1 时被 error1 拒绝。
  • promise2t2 时被 error2 拒绝。
  • Promise.any() 返回一个 Promise,该 Promise 在 t2 时被拒绝,并包含一个 AggregateError,其中包含所有被拒绝的 Promise 的 error1error2

JavaScript Promise.any() 示例

让我们来看一些使用 Promise.any() 方法的示例。

1) 所有 Promise 已完成的示例

以下示例演示了在所有 Promise 已完成的情况下 Promise.any() 方法。

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);
});
Code language: JavaScript (javascript)

输出

Promise 1 fulfilled
Returned Promise
1
Promise 2 fulfilledCode language: JavaScript (javascript)

它是如何工作的。

  • 首先,创建一个新的 Promise p1,它将在 1 秒后解析为值 1
  • 其次,创建一个新的 Promise p2,它将在 2 秒后解析为值 2
  • 第三,使用 Promise.any() 方法,该方法使用两个 Promise p1p2Promise.any() 返回一个 Promise p,它将在 1 秒后解析为第一个已完成的 Promise (p1) 的值 1

2) 一个 Promise 失败的示例

以下示例使用 Promise.any() 方法,该方法使用一个包含失败的 Promise 的 Promise 列表。

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);
});
Code language: JavaScript (javascript)

输出

Promise 1 rejected
Promise 2 fulfilled
Returned Promise
2Code language: JavaScript (javascript)

在此示例中,Promise.any() 会忽略失败的 Promise。当 p2 解析为值 2 时,Promise.any() 返回一个 Promise,该 Promise 解析为与 p2 结果相同的值。

3) 所有 Promise 都失败的示例

以下示例演示了如何在所有 Promise 都失败的情况下使用 Promise.any() 方法。

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);
});
Code language: JavaScript (javascript)

输出

Promise 1 rejected
Promise 2 rejected
Returned Promise
[AggregateError: All promises were rejected] [ 'error1', 'error2' ]Code language: JavaScript (javascript)

在此示例中,p1p2 都被字符串 error1error2 拒绝。因此,Promise.any() 方法被一个包含所有失败 Promise 的错误的 AggregateError 对象拒绝。

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

实际上,您使用 Promise.any() 来返回第一个已完成的 Promise。一旦一个 Promise 完成,Promise.any() 方法就不会等待其他 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>Code language: JavaScript (javascript)

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);
  });
Code language: JavaScript (javascript)

它是如何工作的。

  • 首先,定义 getImageBlob() 函数,该函数使用 fetch API 从 URL 获取图像的 Blob。getImageBlob() 返回一个解析为图像 Blob 的 Promise 对象。
  • 其次,定义两个加载图像的 Promise。
  • 第三,使用 Promise.any() 方法显示第一个可用的图像。

总结

  • 使用 JavaScript Promise.any() 方法来获取一个 Promise 列表,并返回一个首先完成的 Promise。

测验

本教程对您有帮助吗?