Somewhat related, I am working on a front end scripting language that implements this idea, but at the runtime layer:
https://hyperscript.org/docs/#async
Basically, the result of every expression is inspected and, if a Promise is returned, the promise is resolved before execution continues. It's all interpreted and really slow for CPU-intensive stuff, but if you are writing async code that isn't CPU intensive it lets you write stuff in the linear manner:
fetch /message
put it into my innerHTML
One interesting thing that fell out of that work is that you can have event-driven control flow, like a loop that executes until an event is received by an element:https://hyperscript.org/docs/#event-control-flow
<button id="pulsar"
_="on click repeat until event stop
add .pulse then settle
remove .pulse then settle
end">
Click me to Pulse...
</button>