Becuase async()
is a non-blocking function, the result of coroutine launched can’t be returned directly. Instead, coroutine is launched asynchronously and result’s Deferred object is returned immediately which can be used to access the result in future. To access the result from Deferred object, use Deferred#await()
function.
suspend fun Deferred<T>.await(): T
Example :
val client = HttpClient(CIO)
fun main() {
runBlocking {
val res1: Deferred<String> = async { getMathFact(55) }
val res2: Deferred<String> = async { getMathFact(120) }
println("Result1 = ${res1.await()} & Result2 = ${res2.await()}")
}
}
suspend fun getMathFact(num: Int): String {
println("sending R#$num...")
return client.get("http://numbersapi.com/$num/math").bodyAsText()
}
Note that both Coroutines have String
return type (because of getMathFact()
function call), so async()
function returned Deferred<String>
. When invoking Deferred<String>#await()
, we get String
result of coroutine.
⚠️ await()
is a suspend function i.e. it will suspend until the coroutine execution is finished and then only proceed.
The same program can also be written using launch()
function :
val client = HttpClient(CIO)
fun main() {
runBlocking {
launch {
val res = getMathFact(55)
println("Result1 = $res1")
}
launch {
val res = getMathFact(120)
println("Result2 = $res2")
}
}
}
suspend fun getMathFact(num: Int): String {
println("sending R#$num...")
return client.get("http://numbersapi.com/$num/math").bodyAsText()
}
Note that here the output cannot be printed by concatenating the two results as Result1 = $res1 & Result2 = $res2
like we did using async()
. Because when using launch()
, both coroutines execute seperately and there is no in-built mechanism to extract the output of coroutine.
Thus, async()
- await()
functions are useful when working with coroutines that return some output.