Throughout the book, we have written many suspending algorithms, but most of the time it has been done using coroutine builders such as launch(), async(), and runBlocking(). When calling a coroutine builder, the code that we pass to it is a suspending lambda. Now it's time to take a detailed look at how to write suspending code that exists as a function instead:
suspend fun greetDelayed(delayMillis: Int) {
delay(delayMillis)
println("Hello, World!")
}
To create a suspending function, you only need to add the modifier suspend to its signature. Notice that suspending functions can call other suspending functions such as delay() directly – no need to wrap inside a coroutine builder– making our code clean and easy to read.
Nevertheless, if we try calling this function outside of a coroutine it will not work. Consider this example:
fun main(args: Array<String>) {
greetDelayed(1000)
}
This code will not compile because, as we already know, suspending computations can be called only from other suspending computations:
So in order to call this function from non-suspending code, we need to wrap it using a coroutine builder. For example:
fun main(args: Array<String>) {
runBlocking {
greetDelayed(1000)
}
}
Now we have a function that suspends as part of its execution, and that function can be invoked using whichever dispatcher is more convenient at the time – for example, we could call it using a single-thread context.