async/await
Syntax that lets code built on futures read top to bottom: await suspends the function and frees its thread until the result arrives.
How they work
An async function always returns a promise or task. Inside it, await suspends the function until the awaited promise settles and hands control back to the caller; when the value arrives, the function resumes on the next line with ordinary variables and try/catch. The compiler does the work callbacks did by hand: in C#, as in Clojure’s go blocks, it rewrites the function into a state machine that can be paused at each await and resumed later.
C# 5.0 brought the pattern to the mainstream in August 2012, following F#’s asynchronous workflows. Python 3.5 added async def and await (PEP 492, 2015), JavaScript added async functions in ECMAScript 2017, and Rust stabilised async/.await in Rust 1.39 (November 2019). Rust’s are lazy: an async block doesn’t run at all until it’s awaited.
It’s the most readable of the explicit models, but it keeps the two colours: an async function can only be awaited from another async function, and calling it from synchronous code means blocking on it or restructuring the caller.
Sources
- MDN: async function (always returns a promise; await suspends and yields control)
- Rich Hickey: Clojure core.async Channels (28 June 2013)
- Microsoft Learn: The history of C#, C# version 5.0 (released August 2012 with Visual Studio 2012; async and await)
- Wikipedia: Futures and promises (Friedman and Wise 1976; Java 5; F# asynchronous workflows)
- PEP 492: Coroutines with async and await syntax (created April 2015, Python 3.5)
- ECMA-262 8th edition, ECMAScript 2017 (June 2017): introduces async functions
- Rust Blog: Async-await on stable Rust! (November 2019, Rust 1.39)
- Rust std docs: the async keyword (returns a Future; not run until awaited)
- Bob Nystrom: What Color is Your Function? (Feb 2015)