HelloCW
HelloCW

Reputation: 2255

Can I get return actual value if I use launch in Kotlin?

I'm learning Coroutines of Kotlin.

The Code A use async in the coroutines of Kotlin and I can use .await() on a deferred value to get its eventual result, so one.await() will return Int.

If I use launch in the coroutines, can I get the actual value just like one.await()?

Code A

val time = measureTimeMillis {
    val one = async { doSomethingUsefulOne() }
    val two = async { doSomethingUsefulTwo() }
    println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")       

suspend fun doSomethingUsefulOne(): Int {
    delay(1000L) // pretend we are doing something useful here
    return 13
}

suspend fun doSomethingUsefulTwo(): Int {
    delay(1000L) // pretend we are doing something useful here, too
    return 29
}

Upvotes: 1

Views: 617

Answers (3)

Joffrey
Joffrey

Reputation: 37710

There is no [standard non-hacky] way to get the result from launch. This is the whole point of having async.

The 2 functions launch and async have precisely one difference, which is that launch is fire-and-forget, and async allows to wait for a result.

Therefore, there should be no reason for you to want to use launch over async unless you don't need the result, so the question is quite suprising.

Upvotes: 1

Anup Ammanavar
Anup Ammanavar

Reputation: 432

The short answer is NO

As you pointed out async and await will get you the result.

But Launch is used for a different purpose. Its purpose is to act as a bridge between Coroutine and NonCoroutine worlds.

Consider an example of a ViewModel whose coroutine world is controlled by viewModelScope

fun nonCoroutineWorldFunction() {
 ....
 ....
 viewModelScope.launch { 
   // runs in coroutine world
 }
 ....
 ....
 viewModelScope.launch { 
   // runs in coroutine world
 }


}

Launch can be considered something similar to FIRE AND FORGET. You just launch it to do its job rather than waiting for it to do its job

Upvotes: 1

Alexey Romanov
Alexey Romanov

Reputation: 170733

If you use launch, the "actual value" is Unit as you can see from the signature

fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job (source)

so you don't even need to start it.

If you pass a lambda to launch as in

launch { doSomethingUsefulOne() }

it is really

launch { doSomethingUsefulOne(); Unit }

and the value of doSomethingUsefulOne() is thrown away.

Upvotes: 1

Related Questions