Could someone explain why async code needs to be called by async code in a few more words than this? I understand that async-await is just promises under the hood, so it makes sense that any code after an await is equivalent to a callback in then()
. I also have an intuition for why internally the code after an await would need to close over anything before it, if it’s broken up into a separate callback. I don’t understand why it’s closures all the way back to main though?
So with callbacks, promises, async-await, and generators, you ultimately end up taking your asynchronous function and smearing it out into a bunch of closures that live over in the heap.
Your function passes the outermost one into the runtime. When the event loop or IO operation is done, it invokes that function and you pick up where you left off. But that means everything above you also has to return. You still have to unwind the whole stack.
This is where the “red functions can only be called by red functions” rule comes from. You have to closurify the entire callstack all the way back to main() or the event handler.
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/