深入理解Promise.all和Promise.race
在现代的JavaScript编程中,处理异步操作是一个常见的任务。为了更加优雅地处理异步代码,ES6引入了Promise这一概念,它是一种用于处理异步操作的设计模式,提供了一种更结构化、更可靠的方式来处理异步任务。本文将深入探讨JavaScript中的Promise以及其两个常用方法:Promise.race()
和 Promise.all()
。
1. Promise基础概念
Promise是一种表示异步操作的对象,它可以处于三种状态之一:待定(pending)、已解决(fulfilled)和已拒绝(rejected)。在创建一个Promise时,我们可以通过传递一个执行函数来定义异步操作,这个函数接收两个参数:resolve
和 reject
。resolve
用于将Promise从待定状态变为已解决状态,而 reject
用于将Promise变为已拒绝状态。
下面是一个简单的示例,展示了如何创建和使用一个Promise:
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const randomNumber = Math.random();
if (randomNumber > 0.5) {
resolve(randomNumber);
} else {
reject('Random number is too small');
}
}, 1000);
});
myPromise.then(result => {
console.log('Resolved:', result);
}).catch(error => {
console.error('Rejected:', error);
});
2. Promise.race():竞速解决
Promise.race()
方法允许我们同时发起多个异步操作,并在其中一个操作解决(fulfilled)或拒绝(rejected)时得到结果。它的语法如下:
Promise.race([promise1, promise2, ...])
其中,promise1
、promise2
等为Promise对象数组。新的Promise的状态将与第一个解决或拒绝的Promise的状态相同。
考虑这样一个场景,我们需要从多个数据源获取数据,但只关心最快返回的结果。这时,Promise.race()
就派上用场了。例如:
const fetchDataFromSource1 = fetch('https://source1.com/data');
const fetchDataFromSource2 = fetch('https://source2.com/data');
const fetchDataFromSource3 = fetch('https://source3.com/data');
const racePromise = Promise.race([fetchDataFromSource1, fetchDataFromSource2, fetchDataFromSource3]);
racePromise.then(data => {
console.log('Fastest source:', data);
}).catch(error => {
console.error('Error from fastest source:', error);
});
练习: 2637. 有时间限制的 Promise 对象 - 力扣(LeetCode)
题解:
/**
* @param {Function} fn
* @param {number} t
* @return {Function}
*/
var timeLimit = function (fn, t) {
return async function (...args) {
var m = [fn(...args), new Promise((resolve, reject) => {
setTimeout(() => {
reject("Time Limit Exceeded");
}, t);
})];
return Promise.race(m)
}
};
/**
* const limited = timeLimit((t) => new Promise(res => setTimeout(res, t)), 100);
* limited(150).catch(console.log) // "Time Limit Exceeded" at t=100ms
*/
3. Promise.all():等待全部解决
与Promise.race()
不同,Promise.all()
方法要求传入的所有Promise都必须解决(fulfilled)才能得到结果,否则,只要有一个Promise被拒绝(rejected),整个新的Promise就会被拒绝。
使用Promise.all()
可以同时发起多个异步操作,然后等待它们全部完成。这在需要同时获取多个资源并等待全部资源准备好时非常有用。
下面是一个示例,展示如何使用Promise.all()
并行请求多个API数据:
const fetchUserData = fetch('https://api.com/user');
const fetchPosts = fetch('https://api.com/posts');
const fetchComments = fetch('https://api.com/comments');
const allPromise = Promise.all([fetchUserData, fetchPosts, fetchComments]);
allPromise.then(responses => {
const [userData, posts, comments] = responses;
console.log('User data:', userData);
console.log('Posts:', posts);
console.log('Comments:', comments);
}).catch(error => {
console.error('Error:', error);
});
4. 总结
总而言之,Promise是处理异步操作的关键工具,它提供了一种更结构化、更清晰的方式来处理异步任务。通过Promise.race()
可以有效地竞速解决多个异步操作,而 Promise.all()
则可以等待多个异步操作全部完成,从而更高效地处理多个资源的获取和处理。
转载自:https://juejin.cn/post/7270171497988489228