dev3 ·
I have this code and 'done' prints before the items are saved:
items.forEach(async (item) => { await save(item); });
console.log('done');
How do I make it wait?
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
I have this code and 'done' prints before the items are saved:
items.forEach(async (item) => { await save(item); });
console.log('done');
How do I make it wait?
forEach ignores the return value of its callback. An async callback returns a promise, which forEach throws away, so nothing waits for it.
for (const item of items) {
await save(item);
}
console.log('done');
await Promise.all(items.map((item) => save(item)));
console.log('done');
map returns an array of promises and Promise.all waits for all of them. If one rejects, Promise.all rejects immediately (the others keep running). Use Promise.allSettled to get every outcome:
const results = await Promise.allSettled(items.map(save));
const failed = results.filter((r) => r.status === 'rejected');
Firing 5000 requests at once can overload an API or database. Process in chunks:
for (let i = 0; i < items.length; i += 10) {
await Promise.all(items.slice(i, i + 10).map(save));
}
or use a small pool library such as p-limit.
for...of.Promise.all.filter, reduce and some: async callbacks always return truthy promises, so items.filter(async ...) keeps everything.Pitfall: await only works inside an async function or a module top level (ES modules).