IIUC (someone please correct me if I've misunderstood), this is essentially an implementation detail of the underlying operating system/scheduler/runtime. When a suspension point is reached, Swift will yield the thread back to the scheduler, and at some point in the future the rest of the async
function will be scheduled to run.
In UIKit-land, this would (I assume) mean handing control back to the main RunLoop
so that it can continue to service UI events until the rest of the async
task is ready to run.
As for the chicken-egg problem with async
function calls, there have been a couple solutions mentioned which will allow non-async
functions to spawn async
execution contexts.