Array.prototype.forEach can not be used for asynchronous code. (It could not be used with promises, and it can not be used with async-await.)
The following forEach loop might not do what it looks like:
const players = await this.getWinners();
players.forEach(async (player) => {
await givePrizeToPlayer(player);
});
await sendEmailToAdmin('All prizes awarded');What's wrong with it?
- The promises returned by the iterator function are not handled. If one of them throws an error, the error won't be caught.
- The prizes are awarded in parallel, not serial (one by one).
- The loop finishes iterating before any of the prizes have been awarded.
- As a result, sendEmailToAdmin sends the email before the prizes have been awarded. Maybe none of them were awarded (they could have all thrown an error)!
for (const player of players) {
await givePrizeToPlayer(player);
}await Promise.all(players.map(async (player) => {
await givePrizeToPlayer(player);
}));await players.reduce(async (a, player) => {
await a;
await givePrizeToPlayer(player);
}, Promise.resolve());Some people recommend this approach as more "functional" but I find the for-of loop is clearer.