Is the following a good explanation of Async/Await…
Async/Await requires a runner or executor with a stack of pending Async state machines that it then pops and the state transition functions of.
An Async is a state machine instances (a value). That is, it is a set of possible states, a current state, and a transition graph implemented by a function whose inputs are local environment values and the current state. When the transition function is invoked it transitions the Async current state to the next state and returns it to the invoker which pushes the Async value back onto the queue or discards it depending on the current state, then returns to the runner the current status of Done or Pending.
Await is a stacking function implemented by the Async value that pushes its Async onto the stack of the runner which eventually dequeues it and invokes its transition function.
When an Async transition function reaches an Await action it updates its current state value, enqueues the associated Async, and returns to the runner the current status of Done or Pending.
The runner is a key often overlooked semantic aspect of the Async/Await model.