JavaScript Promise.all
在JavaScript中,Promise.all方法可以同时处理多个Promise对象,并在所有Promise对象都成功时返回一个新的Promise对象。这个新的Promise对象将包含所有Promise对象的结果,如果有一个Promise对象失败,则整个Promise.all也会失败。
基本用法
下面是一个简单的示例,展示了如何使用Promise.all方法:
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.all([promise1, promise2])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,我们创建了两个Promise对象,分别在1秒和2秒后resolve。然后我们使用Promise.all方法来同时处理这两个Promise对象,当它们都成功时,我们打印出结果。
处理Promise失败
如果其中一个Promise对象失败,整个Promise.all也会失败。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('Promise 2 rejected');
}, 2000);
});
Promise.all([promise1, promise2])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
在上面的示例中,promise2被reject,导致整个Promise.all失败,我们在catch中捕获到了错误。
处理多个异步请求
Promise.all方法非常适合处理多个异步请求,下面是一个示例:
const fetchData = (url) => {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => response.json())
.then(data => resolve(data))
.catch(error => reject(error));
});
};
const urls = [
'https://api.deepinout.com/users/1',
'https://api.deepinout.com/users/2',
'https://api.deepinout.com/users/3'
];
Promise.all(urls.map(url => fetchData(url)))
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
在上面的示例中,我们定义了一个fetchData函数来获取指定URL的数据,然后使用Promise.all方法来处理多个异步请求。
处理不同类型的Promise对象
Promise.all方法可以处理不同类型的Promise对象,例如普通Promise对象和async函数返回的Promise对象。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
const promise2 = async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 2 resolved');
}, 2000);
});
};
Promise.all([promise1, promise2()])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,promise2是一个async函数,返回一个Promise对象,我们也可以将其放入Promise.all中处理。
处理空数组
如果传入的Promise数组为空,Promise.all会立即resolve。下面是一个示例:
Promise.all([])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,由于传入的Promise数组为空,Promise.all会立即resolve,并且结果是一个空数组。
处理非Promise对象
如果传入的数组中有非Promise对象,Promise.all会将其转换为Promise对象。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
const nonPromise = 'Not a Promise';
Promise.all([promise1, nonPromise])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,我们传入了一个非Promise对象,Promise.all会将其转换为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);
});
const timeoutPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('Timeout');
}, 1500);
});
Promise.all([promise1, promise2, timeoutPromise])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
在上面的示例中,我们传入了一个超时Promise对象,如果在1.5秒内没有获取到所有Promise对象的结果,则会返回一个超时错误。
处理重复Promise对象
如果传入的Promise数组中有重复的Promise对象,Promise.all只会处理一次。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
Promise.all([promise1, promise1])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,我们传入了两个相同的Promise对象,但Promise.all只会处理一次。
处理不同类型的结果
Promise.all方法会按照传入Promise对象的顺序返回结果,即使Promise对象的执行顺序不同。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 2000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 2 resolved');
}, 1000);
});
Promise.all([promise1, promise2])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,promise1的执行时间比promise2长,但Promise.all会按照传入Promise对象的顺序返回结果。
处理不同类型的错误
如果传入的Promise对象中有不同类型的错误,Promise.all会返回第一个错误。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Promise 2 rejected'));
}, 2000);
});
Promise.all([promise1, promise2])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
在上面的示例中,promise2返回了一个Error对象,导致整个Promise.all返回了这个错误。
处理不同类型的结果和错误
如果传入的Promise对象中有不同类型的结果和错误,Promise.all会返回第一个错误。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Promise 2 rejected'));
}, 2000);
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 3 resolved');
}, 1500);
});
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
在上面的示例中,promise2返回了一个Error对象,导致整个Promise.all返回了这个错误。
处理不同类型的Promise对象和非Promise对象
如果传入的数组中有不同类型的Promise对象和非Promise对象,Promise.all会将非Promise对象转换为Promise对象。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
const nonPromise = 'Not a Promise';
Promise.all([promise1, nonPromise])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,我们传入了一个非Promise对象,Promise.all会将其转换为Promise对象。
处理大量Promise对象
Promise.all方法可以处理大量的Promise对象,但需要注意内存消耗。下面是一个示例:
const promises = [];
for (let i = 0; i < 1000; i++) {
promises.push(new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Promise ${i} resolved`);
}, 1000);
}));
}
Promise.all(promises)
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,我们创建了1000个Promise对象,并使用Promise.all方法来处理它们。
处理异步操作
Promise.all方法可以处理异步操作,例如定时器。下面是一个示例:
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 1 resolved');
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Promise 2 resolved');
}, 2000);
});
const timerPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Timer resolved');
}, 1500);
});
Promise.all([promise1, promise2, timerPromise])
.then((results) => {
console.log(results);
})
.catch((error) => {
console.error(error);
});
代码运行结果:
在上面的示例中,我们传入了一个定时器Promise对象,Promise.all可以处理这种异步操作。
总结
通过本文的介绍,我们了解了JavaScript中Promise.all方法的基本用法和各种应用场景。Promise.all方法可以同时处理多个Promise对象,非常适合处理多个异步请求或并行操作。同时,我们也学习了如何处理不同类型的Promise对象和错误,以及如何处理超时和空数组等特殊情况。