awaitcreates a state machine that creates the illusion of “pausing” execution at the
awaitinvocation. Actually, the function is split in two (pre-await, post-await), the pre-await bit is called, the
awaited operation is triggered, and the post-await bit is scheduled to run when the
awaited operation is done, and the event loop keeps going.
This sounded very familar, and it looks like this is a lot like
goblocks in Clojure’s
go is a macro that takes its body and examines it for any channel operations. It will turn the body into a state machine. Upon reaching any blocking operation, the state machine will be ‘parked’ and the actual thread of control will be released. This approach is similar to that used in C# async. When the blocking operation completes, the code will be resumed (on a thread-pool thread, or the sole thread in a JS VM). In this way the inversion of control that normally leaks into the program itself with event/callback systems is encapsulated by the mechanism, and you are left with straightforward sequential code. It will also provide the illusion of threads, and more important, separable sequential subsystems, to ClojureScript.
Does this imply that
awaitis simply not possible in non-event loop models, like Java? This is possibly why Clojure
goblocks are restricted to thread pools in Java; this gives the system a next thing to work on while a thread-of-execution is paused on a blocking operation.
(from notes on What Color is Your Function?)