Могу ли я получить фактическое значение возврата, если использую запуск в Kotlin? - PullRequest
0 голосов
/ 19 марта 2020

Я изучаю сопрограммы Kotlin.

Код A использует async в сопрограммах Kotlin, и я могу использовать .await() для отложенного значения, чтобы получить его возможный результат, поэтому one.await() вернет Int.

Если я использую launch в сопрограммах, могу ли я получить фактическое значение так же, как one.await()?

Код 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
}

Ответы [ 3 ]

1 голос
/ 19 марта 2020

Короткий ответ: НЕТ

Как вы указали, async и await даст вам результат.

Но Launch используется для другая цель. Его цель - действовать как мост между мирами Coroutine и NonCoroutine.

Рассмотрим пример модели ViewModel, чей мир сопрограмм управляется viewModelScope

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


}

Launch можно считать чем-то похожим на FIRE AND FORGET. Вы просто запускаете его, чтобы выполнять свою работу, а не ждете, пока он выполнит свою работу

1 голос
/ 19 марта 2020

Нет [стандартного нехакерского] способа получить результат от launch. В этом весь смысл того, что async.

2 функции launch и async имеют только одно различие, а именно: launch - это огонь и забыл, а async позволяет ждать результата.

Поэтому у вас не должно быть причин использовать launch вместо async, если вам не нужен результат, поэтому вопрос весьма удивителен.

1 голос
/ 19 марта 2020

Если вы используете launch, «фактическое значение» будет Unit, как вы можете видеть из подписи

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

, поэтому вам даже не нужно запускать Это.

Если вы передаете лямбду на launch, как в

launch { doSomethingUsefulOne() }

, это действительно

launch { doSomethingUsefulOne(); Unit }

и значение doSomethingUsefulOne() выбрасывается.

...