摘要:在本教程中,您将学习如何使用 JavaScript Promise.any() 方法来组合 Promise。
JavaScript Promise.any() 方法简介
Promise.any() 方法接受一个 Promise 对象列表作为 可迭代对象
Promise.any(iterable);Code language: JavaScript (javascript)如果可迭代对象中的 Promise 之一已完成,则 Promise.any() 将返回一个单个 Promise,该 Promise 解析为一个值,该值是已完成 Promise 的结果。
在此图中
promise1在t1时解析为值v1。promise2在t2时解析为值v2。Promise.any()返回一个 Promise,该 Promise 在t1时解析为值v1,即promise1的结果。
Promise.any() 返回一个 Promise,该 Promise 将使用第一个已完成的 Promise 完成,即使可迭代对象中的某些 Promise 失败了。
在此图中
promise1在t1时被error拒绝。promise2在t2时被完成为值v2。Promise.any()返回的 Promise 解析为值v2,即promise2的结果。请注意,Promise.any()方法会忽略失败的 Promise (promise1)。
如果可迭代对象中的所有 Promise 都失败,或者可迭代对象为空,则 Promise.any() 返回一个 Promise,该 Promise 被一个包含所有拒绝原因的 AggregateError 拒绝。AggregateError 是 Error 的子类。
在此图中
promise1在t1时被error1拒绝。promise2在t2时被error2拒绝。Promise.any()返回一个 Promise,该 Promise 在t2时被拒绝,并包含一个AggregateError,其中包含所有被拒绝的 Promise 的error1和error2。
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()方法,该方法使用两个 Promisep1和p2。Promise.any()返回一个 Promisep,它将在 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)在此示例中,p1 和 p2 都被字符串 error1 和 error2 拒绝。因此,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。