https://kotlinlang.org logo
Title
f

Fernando Branbila Cunha Junior

09/08/2020, 12:45 AM
I'm very new to Kotlin and so, to co-routines. I'm trying the following snippet, but the program always finishes before printing "data". Could'nt make progress out of it
fun main() {
    GlobalScope.launch {
        val deferredUser = getUserByIdAsync(1)
        val data = deferredUser.await()
        print(data)
    }
}


private suspend fun getUserByIdAsync(userId: Int) =
        GlobalScope.async {
            println("Retrieving user from network")
            delay(3000)
            println("Still on coroutine")
            User(userId, "John", "Silva")
        }
a

Adam Powell

09/08/2020, 1:04 AM
You've illustrated the reasons structured concurrency exists. 🙂 Your
main
ends before the coroutine it launches completes, or perhaps even before it begins. Idiomatically one does not return
Deferred
from functions and instead declares functions as
suspend
that need to do suspending work. Your code would be better rewritten as:
suspend fun main() {
    val user = getUserById(1)
    print(data)
}

private suspend fun getUserById(userId: Int) {
    println("Retrieving user from network")
    delay(3000)
    return User(userId, "John", "Silva")
}
A caller that wishes to fetch two users concurrently could do so with the following:
suspend fun fetchTwo() = coroutineScope {
    val one = async { getUserById(1) }
    val two = async { getUserById(2) }
    println("user one: ${one.await()} two: ${two.await()}")
}
f

Fernando Branbila Cunha Junior

09/08/2020, 1:18 AM
Thanks @Adam Powell. I got it to work with your example. What i can't still undertand is why it only works while the "main" is suspended. How can i get the same result without it being suspend? And sorry in advance if it's a stupid question
a

Adam Powell

09/08/2020, 1:52 AM
You have to be in a suspending function to await a result or join a launched job. When main returns, your program ends. Therefore you have to wait for your suspending job to finish.
j

julian

09/08/2020, 2:25 AM
@Fernando Branbila Cunha Junior main doesn't have to be a suspend function. But in that case, for it to call a suspend function, it would have to do so by wrapping the call in something that bridges suspend and non-suspend code - like
runBlocking
.