This could be solved by using for..of in an asnyc function though.
It might look like surprsising behavior maybe, but putting the async keyword outside and looping without non-awaited callbacks is the only possible way to keep the semantics sound, no?
In other words, forEach would have to return a Promise too.
That's where the function coloring rightfully annoys programmers to catch their mistakes, there are if cause also lint rules for this.
AFAIK there are two active proposals that aim to provide this natively (and additonaly enable working with lazy and/or infinite iterators or generator functions):
AsyncIterator and
tc39/proposal-async-iterator-helpers
Things don’t have to be that way. You can reject the use of async/await in contexts that aren’t aware of it (delegating it to special APIs that properly handle it).
Having fun using async/await in loops? https://zellwk.com/blog/async-await-in-loops/
An actual blocking model is much easier to grok.