But first, let's talk about for
loops!
I don't like for
loops as they tend to promote bad coding practices, like nested loops that do a lot of things at once or continue
/break
statements scattered around that quickly descend into an unmaintainable mess.
Also, a more functional approach with functions like map
/filter
/reduce
promote a style where one function does only one thing and everything inside it is scoped and stateless. And the functional approach is not only possible 99% of the time but it comes with no perceivable performance drop and it also yields simpler code (well, at least when you know the functions involved).
But async/await is in the remaining 1%.
For loops have a distinctive feature, as they don't rely on calling a function. In effect, you can use await
inside the loop and it will just work.
// synchronous
{
const res = [];
for (let i of [1, 2, 3]){
res.push(i + 1);
}
// res: [2, 3, 4]
}
// asynchronous
{
const res = [];
for (let i of [1, 2, 3]){
await sleep(10);
res.push(i + 1);
}
// res: [2, 3, 4]
}
As for
loops are a generic tool, they can be used for all kinds of requirements when working with collections.
But their downside is still present, and while it's not trivial to adapt the functional approach to async/await, once you start seeing the general pattern it's not that hard either.