I'm very new to Kotlin and so, to co-routines. I'm...
# coroutines
f
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
Copy code
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
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:
Copy code
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:
Copy code
suspend fun fetchTwo() = coroutineScope {
    val one = async { getUserById(1) }
    val two = async { getUserById(2) }
    println("user one: ${one.await()} two: ${two.await()}")
}
f
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
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
@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
.