promise.any() 的类型签名是:
Promise.any<T>(promises: Iterable<Promise<T>>): Promise<T>
Promise.any() 返回一个 Promise p。它的结果取决于参数 promises(迭代 Promises 的结果引用):
如果有一个 Promise 的状态为成功(fulfilled),p 的状态为成功(resolved)。
如果所有的 Promises 都失败,p 的状态将失败(rejected),结果值是包含所有失败状态的 AggregateError 的实例的结果集。
AggregateError 的类型签名是(删除了一些成员):
class AggregateError {
constructor(errors: Iterable<any>, message: string);
get errors(): Array<any>;
get message(): string;
}
展示一个 Promise 成功时发生了什么:
const promises = [
Promise.reject('ERROR A'),
Promise.reject('ERROR B'),
Promise.resolve('result'),
];
Promise.any(promises)
.then((result) => assert.equal(
result, 'result'
));
展示一个 Promise 失败时发生了什么:
const promises = [
Promise.reject('ERROR A'),
Promise.reject('ERROR B'),
Promise.reject('ERROR C'),
];
Promise.any(promises)
.catch((aggregateError) => assert.deepEqual(
aggregateError.errors,
['ERROR A', 'ERROR B', 'ERROR C']
));
Promise.any() 与 Promise.all() 对比
有两个方法对比 Promise.any() 和 Promise.all():
- 它们彼此相反:
Promise.all(): 第一个输入拒绝将拒绝结果 Promise 或它的实现值是一个具有输入实现值的数组。
Promise.any(): 第一个输入实现满足结果 Promise 或它的拒绝值是一个带有输入拒绝值的数组。
- 有不同的重点:
Promise.all() 对所有成功感兴趣。相反的情况(至少一个拒绝)导致拒绝。
Promise.any() 对第一个实现很感兴趣。相反的情况(仅拒绝)导致拒绝。
Promise.any() 与 Promise.race() 对比
Promise.any() 和 Promise.race() 也可以联系起来,但有趣的是它们的不同:
- Promise.race() 对完成感兴趣。首先完成的 Promise 是“胜利”。换句话说:我们想知道首先完成的异步计算。
- Promise.any() 对成功感兴趣。首先成功的 Promise 是“胜利”。换句话说:我们想知道首先成功的异步计算。
主要(相对罕见)的用例 .race() 是超时 Promises。.any() 的用例范围更广。接下来,我们来看它们。
Promise.any() 的用例
如果我们有多个异步计算,同时仅仅对第一个成功的感兴趣,就可以使用 Promise.any()。在某种程度上,我们让计算彼此竞争,并使用最快的一个
以下代码演示了下载资源时的展示:
const resource = await Promise.any([
fetch('https://example.com/first.txt')
.then((response) => response.text()),
fetch('https://example.com/second.txt')
.then((response) => response.text()),
]);
我们可以使用相同的模式来使用更快下载的模块:
const lodash = await Promise.any([
import('https://primary.example.com/lodash'),
import('https://secondary.example.com/lodash'),
]);
作为比较,下面的代码展示我们在主服务器出错时使用备份的第二服务器:
let lodash;
try {
lodash = await import('https://primary.example.com/lodash');
} catch {
lodash = await import('https://secondary.example.com/lodash');
}