摘要:在本教程中,您将学习如何使用 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 fulfilled
Code 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
2
Code 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。