Promise.race() 原理解析及使用指南
source link: https://my.oschina.net/lav/blog/5233697
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Promise
对象是 ECMAScript 6 中新增的对象,主要将 JavaScript 中的异步处理对象和处理规则进行了规范化。前面介绍了《Promise.any() 原理解析及使用指南》、《Promise.all() 原理解析及使用指南》和《Promise.allSettled() 原理解析及使用指南》,本文继续来介绍 Promise
另一个方法 Promise.race(promises)
,顾名思义就是赛跑的意思,Promise.race([p1, p2, p3])
里面 promise
数组那个执行完成得快就获取那个的结果,不管结果本身是成功履行状态还是失败拒绝状态,只输出最快的 promise
。
下面来看看 Promise.race()
是如何工作的。
1.工作原理
Promise.race()
返回一个 promise
,一旦迭代器中的某个 promise
履行或拒绝,返回的 promise
就会履行或拒绝。
函数接受一个 promise
数组(或通常是一个可迭代的)作为参数,如下:
const racePromise = Promise.race(promises);
当所有输入 promises
中有一个 promise
快速被履行或拒绝时,racePromise
就会解析快速完成的 promise
结果(履行或拒绝):
可以使用 then
方法提取 racePromise
的结果:
racePromise.then((fastValue) => {
fastValue // 快速完成的 promise
});
也可以使用 async/await
语法:
const fastPromise = await racePromise;
fastPromise; // 快速完成的 promise
Promise.race()
返回的承诺和最先完成的承诺信息一致。
Promise.race()
和Promise.any()
的不同:Promise.race()
承诺列表中寻找第一个履行或拒绝的承诺;Promise.any()
是从承诺列表中查找第一个履行的承诺。
2. 使用指南
现在来深入介绍 Promise.race()
的使用之前,同样先来定义 2 个简单的函数。
function resolveTimeout(value, delay) {
return new Promise((resolve) => setTimeout(() => resolve(value), delay));
}
function rejectTimeout(reason, delay) {
return new Promise((r, reject) => setTimeout(() => reject(reason), delay));
}
接下来使用上面定义的2个辅助函数来试试 Promise.race()
。
2.1 完成所有 promises
下面定义了一个 promise
数组 racePromise
,所有的 promise
都能够成功的 resolve
值,如下:
const fruits = ["potatoes", "tomatoes"];
const vegetables = ["oranges", "apples"];
const racePromise = Promise.race([
resolveTimeout(fruits, 5000),
resolveTimeout(vegetables, 1000),
]);
// 等待 1 秒 ...
const list = async () => {
try {
const fastPromise = await racePromise;
console.log(fastPromise);
} catch (error) {
console.log(error);
}
};
list(); // [ 'oranges', 'apples' ]
从上面执行的结果来看 Promise.race()
返回最快履行的 promise
的 resolve
结果。
2.2 一个 promise
被 rejected
将上面第一个 promise
出现异常被 rejected
,如下代码:
const fruits = ["potatoes", "tomatoes"];
const racePromise = Promise.race([
resolveTimeout(fruits, 2000),
rejectTimeout(new Error("Vegetables is empty"), 1000),
]);
// 等待 1 秒 ...
const list = async () => {
try {
const fastPromise = await racePromise;
console.log(fastPromise);
} catch (error) {
console.log(error);
}
};
list(); // Error: Vegetables is empty
从上面的结果看,最先完成的 promise
被 rejected
,那么 fastPromise
返回的 promise
也是被 rejected
。
下面将rejected
的承诺时间延长到 5秒,如下:
const fruits = ["potatoes", "tomatoes"];
const racePromise = Promise.race([
resolveTimeout(fruits, 2000),
rejectTimeout(new Error("Vegetables is empty"), 5000),
]);
// 等待 2 秒 ...
const list = async () => {
try {
const fastPromise = await racePromise;
console.log(fastPromise);
} catch (error) {
console.log(error);
}
};
list(); // [ 'potatoes', 'tomatoes' ]
从上面执行结果看到,最快完成的 promise
履行了 resolve
,那么 fastPromise
返回的 promise
也是履行了 resolve
。
2.3 所有 promises
被 rejected
将上面所有的 promises
出现异常被 rejected
,如下代码:
const racePromise = Promise.race([
rejectTimeout(new Error("Fruits is empty"), 2000),
rejectTimeout(new Error("Vegetables is empty"), 1000),
]);
// 等待 1 秒 ...
const list = async () => {
try {
const fastPromise = await racePromise;
console.log(fastPromise);
} catch (error) {
console.log(error);
}
};
list(); // Error: Vegetables is empty
从结果来看,虽然两个承诺都被拒绝了,fastPromise
返回的 promise
是最快被拒绝的 。
3. 使用场景
3.1. 性能测试
在有异步操作的项目中,在对于网络或数据库请求进行性能进行优化的时候,可以使用 Promises
来测试其优化效果,通过使用 Promise.race()
来测试两种不同的方法的响应速度。
3.2 最佳选择
例如获取同一类型的数据有多个请求服务器,同时向多个服务器发送请求,只要其中一个完成工作,就将其数据呈现,达到选择最佳线路的效果。这是可以使用 Promise.race()
同时执行 promise
并在第一个成功后立即完成。
文章介绍了 Promise.race()
原理和使用,另外增加了2个可能用得到的场景,而Promise.race()
和 Promise.any()
之间的基本区别在于,Promise.race()
为第一个已解决和已拒绝的 promise
执行回调函数,而 Promise.any()
为第一个已履行的 promise
执行回调函数,如果没有履行的 promise
则拒绝一个特殊属性 AggregateError
。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK