Using await one after another runs tasks in sequence: each one waits for the previous one to finish. That's what you want when each step needs the previous result. But if the tasks are independent, waiting for each in turn is a waste of time.
Imagine making breakfast. You could boil the kettle, wait for it, then make toast, wait for it, then fry an egg. Or you could start all three at once and be done in a third of the time.
Promise.all takes an array of promises, runs them all at the same time, and gives you back a promise for an array of all their results:
function wait(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function makeItem(name, ms) {
await wait(ms);
return name;
}
async function breakfast() {
const start = Date.now();
const [tea, toast, egg] = await Promise.all([
makeItem("☕ tea", 300),
makeItem("🍞 toast", 200),
makeItem("🍳 egg", 300),
]);
const seconds = Math.round((Date.now() - start) / 100) / 10;
console.log(`Breakfast is ready: ${tea}, ${toast}, ${egg}`);
console.log(`Total time: about ${seconds} seconds`);
}
breakfast();
It prints
Breakfast is ready: ☕ tea, 🍞 toast, 🍳 egg Total time: about 0.3 seconds
All three items were "cooked" at the same time, so the whole breakfast took 0.3 seconds (the time of the slowest item), not 0.8 seconds (all three added up).
If any of the promises rejects, Promise.all rejects immediately. If you'd rather wait for all of them and see which ones worked and which ones failed, use Promise.allSettled instead.