Kotlin’s async/await pattern starts independent computations concurrently and then suspends until their results are available. async returns Deferred<T>; await retrieves its value without blocking the underlying thread. section 14.6.3 section 1.2.4
Listing 14.7 Using the async coroutine builder to start a new coroutine
suspend fun slowlyAddNumbers(a: Int, b: Int): Int {
log("Waiting a bit before calculating $a + $b")
delay(100.milliseconds * a)
return a + b
}
fun main() = runBlocking {
log("Starting the async computation")
val myFirstDeferred = async { slowlyAddNumbers(2, 2) } #1
val mySecondDeferred = async { slowlyAddNumbers(4, 4) } #1
log("Waiting for the deferred value to be available")
log("The first result: ${myFirstDeferred.await()}") #2
log("The second result: ${mySecondDeferred.await()}") #2
}
Start two slowlyAddNumbers calls with async, then call await on each Deferred. The computations overlap, so total time follows the longer operation rather than their sum. section 14.6.3 section 14.6.3
The builder invocation itself does not suspend the surrounding coroutine. It creates work immediately; the surrounding coroutine suspends only when await needs a result. In the example, both additions begin before either result is requested. section 14.6.3
Use async/await selectively:
- Choose async when independent tasks should run concurrently and their values must be combined. section 14.6.3
- Prefer ordinary sequential suspending-function calls when concurrency is unnecessary; async is not required for every asynchronous operation. section 14.6.3
- Keep related async operations in one coroutine scope so failure in one loading process can cancel the other automatically. section 1.2.4
Handling a failed Deferred
A failed async computation does not produce a value. Calling await rethrows its exception, so surround await with try-catch when the caller should handle the failure. An uncaught child exception can still propagate to its parent coroutine. section 18.1 section 18.3.1
This pattern resembles a Future or Promise: Deferred represents a value whose computation is still in progress. It provides readable consecutive logic without callback-heavy control flow while retaining structured coroutine lifetimes. section 14.6.3 section 1.2.4
















