When a function is suspended inside a coroutine, the coroutine state is saved, and nothing else happens in that coroutine until the suspended function is resumed. This sequential behavior is what we want when we have dependencies or ordering between functions—just like you would see in normal imperative code.
Let's look at the following example:
fun main() {
suspend fun a() {
delay(100)
println("a")
}
suspend fun b() {
delay(100)
println("b")
}
runBlocking {
a()
b()
println("Done")
}
}
When this function executes, the following will be printed:
a
b
Done
The runBlocking builder call creates a coroutine and immediately invokes the suspending a function. The a function suspends for 100 milliseconds then resumes and prints a. The second suspending b function is invoked next and similarly sleeps...