Learning paths / Async without the mystery
Async without the mystery
Event loops, await, and what blocks them, in JavaScript, Python, C#, Rust and Kotlin.
- The JavaScript event loop: microtasks before timersJavaScript · BasicsOne thread runs the whole script first. Then every microtask (the promise), and only then the next task (the timeout).
- A CPU-heavy loop blocks the JavaScript event loopJavaScript · BasicsA ticker logs every 20 ms. A 200 ms busy loop holds the only JS thread, so no tick runs until it ends.
- time.sleep vs asyncio.sleep: blocking the event loopPython · Basicsslow_call uses time.sleep inside a coroutine. It blocks the loop's only thread, so the ticker can't tick until it ends.
- Which thread runs the code after await?C# · IntermediateFetchAsync starts on the caller's thread. After await Task.Delay, the rest of it, and of Main, runs on a thread-pool thread.
- The .Result deadlock on a UI threadC# · AdvancedA click handler blocks the UI thread in .Result. The rest of LoadAsync needs that same thread, so neither can go on.
- Tokio tasks switch only at .awaitRust · IntermediateTwo tasks share one thread. They take turns, and every switch happens at an .await.
- Blocking in async code stalls every taskRust · Intermediatemain calls a blocking sleep on the runtime's only thread. The ticker can't tick until it ends.
- Kotlin coroutines take turns on one threadKotlin · BasicsTwo coroutines share the main thread. Each delay() suspends one and frees the thread for the other.