How to wait for a promise within a loop block
JavaScript promises enable developers to write asynchronous applications in JavaScript
Loops are ways of iterating elements
For instance doing an asynchronous task within a for loop can be done as follows;
Note that lag is used to emulate some delay.
const items = [1, 2, 3, 4]
const lag = async (delay) => {
return new Promise((resolve) =>
setTimeout(() => res(`${delay / 1000} sec`), delay))
}
items.forEach(async (item) => {
const seconds = await lag(1000 * item)
console.log(seconds)
})
expected output
1 sec
2 sec
3 sec
4 sec
After running the code above every second some text was printed
This won't work as expected. Try adding a console.log after the forEach call. It will log before all other lag calls resolve. This is in most cases not indented.
ReplyDeleteThis should do the job:
const allPromises = await Promise.all(items.map(async i => {
await lag(i * 1000);
console.log(i + " sec");
}));
console.log("done");
This code will execute all async functions in parallel and waits until the last Promise resolves.
If you want to wait for the previous Promise to resolve before starting the next one, switch the Array.map function with reduce, and await the accumulator Promise.
I really like your blog! Keep learning in public. With your pace of learning new things you will achieve your goals in no time 👍🏻💪🏻
ReplyDeleteTim, promise all is a good alternative too.
ReplyDeleteI created a CodeSandBox to make it more clear what I meant.
ReplyDeletehttps://codesandbox.io/s/hungry-chaum-ezh7v
The forEach version looks like it works, but you never know, when all Promises are done. This behavior can lead to nasty bugs.
The CodeSandBox illustration is clear.
ReplyDeleteI see the significance of using primise all ,
especially in a production environment.