在 JavaScript 中,Promise 是一种用于处理异步操作的对象,它让我们可以更优雅地处理异步任务,避免了回调地狱的问题。而 Promise.race
作为 Promise 组合的重要方法之一,有着独特的应用场景。本文将深入探讨 Promise.race
的原理、用法以及实际应用。
Promise.race
方法接收一个可迭代对象(通常是数组)作为参数,这个数组中的每个元素都应该是一个 Promise 对象。它会返回一个新的 Promise 实例,这个新 Promise 会在数组中的任何一个 Promise 率先解决(resolved)或拒绝(rejected)时,立即以相同的状态和结果进行解决或拒绝。其基本语法如下:
Promise.race(iterable);
Promise.race
就像是一场赛跑,数组中的每个 Promise 都是一名选手。一旦有一个选手冲过终点线(即 Promise 被解决或拒绝),比赛就结束了,Promise.race
返回的新 Promise 也会以这个率先完成的 Promise 的状态和结果为准。
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 2 resolved');
}, 2000);
});
Promise.race([promise1, promise2])
.then((result) => {
console.log(result); // 输出: Promise 1 resolved
})
.catch((error) => {
console.error(error);
});
在这个例子中,promise1
会在 1 秒后解决,而 promise2
会在 2 秒后解决。由于 promise1
率先完成,所以 Promise.race
返回的 Promise 会以 promise1
的解决结果进行解决,最终输出 Promise 1 resolved
。
在实际开发中,我们经常会遇到网络请求,但有时候请求可能会因为各种原因(如服务器故障、网络延迟等)而长时间没有响应。这时,我们可以使用 Promise.race
来设置请求超时,避免用户长时间等待。
function fetchWithTimeout(url, timeout) {
const fetchPromise = fetch(url);
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => {
reject(new Error('Request timed out'));
}, timeout);
});
return Promise.race([fetchPromise, timeoutPromise]);
}
fetchWithTimeout('https://api.example.com/data', 5000)
.then((response) => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok');
})
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
});
在这个例子中,我们创建了两个 Promise:一个是 fetchPromise
用于发起网络请求,另一个是 timeoutPromise
用于设置超时。使用 Promise.race
将这两个 Promise 组合起来,如果在 5 秒内请求没有完成,timeoutPromise
会率先拒绝,从而触发 catch
块,提示用户请求超时。
当我们需要从多个数据源加载相同或相似的资源时,可以使用 Promise.race
来选择最快返回结果的数据源。
const source1 = new Promise((resolve) => {
setTimeout(() => {
resolve('Data from source 1');
}, 2000);
});
const source2 = new Promise((resolve) => {
setTimeout(() => {
resolve('Data from source 2');
}, 1000);
});
Promise.race([source1, source2])
.then((data) => {
console.log(data); // 输出: Data from source 2
})
.catch((error) => {
console.error(error);
});
在这个例子中,我们模拟了从两个不同数据源加载数据的过程。由于 source2
会在 1 秒后返回数据,而 source1
会在 2 秒后返回数据,所以 Promise.race
会选择 source2
的结果。
特性 | 详情 |
---|---|
语法 | Promise.race(iterable) |
原理 | 多个 Promise 竞争,率先完成的 Promise 决定 Promise.race 返回 Promise 的状态和结果 |
应用场景 | 设置请求超时、竞争加载资源等 |
Promise.race
为我们处理异步操作提供了一种强大而灵活的方式,通过合理运用它,我们可以优化代码逻辑,提高应用的性能和用户体验。在实际开发中,当我们需要处理多个异步任务并关注最快完成的结果时,不妨考虑使用 Promise.race
。