https://kotlinlang.org logo
#coroutines
Title
# coroutines
n

Nino

08/11/2022, 1:46 PM
Is there a better way to keep parallelism in the
initializeStuffAndGetFoo()
function between my coroutines without this dangerous
first() as String
? https://pl.kotl.in/7fVqO3EXP
Copy code
import kotlinx.coroutines.*

fun main() = runBlocking {
    println(initializeStuffAndGetFoo())
}

suspend fun initializeStuffAndGetFoo() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
    listOf(
        async { getFooValue() },
        async { initA() },
        async { initB() },
    ).awaitAll().first() as String
}

suspend fun getFooValue(): String {
    delay(2_000)
    return "Foo"
}

suspend fun initA() = delay(1_000)
suspend fun initB() = delay(3_000)
I forgot that
async
starts eagerly by default so we can use something like that, can't we ?
Copy code
import kotlinx.coroutines.*

fun main() = runBlocking {
    println(initializeStuffAndGetFoo())
}

suspend fun initializeStuffAndGetFoo() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
    val fooAsync = async { getFooValue() }
    listOf(
        async { initA() },
        async { initB() },
    ).awaitAll()

    fooAsync.await()
}

suspend fun getFooValue(): String {
    delay(2_000)
    return "Foo"
}

suspend fun initA() = delay(1_000)
suspend fun initB() = delay(3_000)
j

Joffrey

08/11/2022, 2:03 PM
You also don't even need to launch the other 2 using
async
, you could use
lauch
for the other 2 and not even await them (
withContext
would do it)
n

Nino

08/11/2022, 2:05 PM
Wouldn't
initA()
and
initB()
become sequential this way ?
Nevermind, I need to use 2 launches obviously. The heat is killing my brain lol Final code ? :
Copy code
import kotlinx.coroutines.*

fun main() = runBlocking {
    println(initializeStuffAndGetFoo())
}

suspend fun initializeStuffAndGetFoo() = coroutineScope {
    launch { initA() }
    launch { initB() }
    getFooValue()
}

suspend fun getFooValue(): String {
    println("Waiting for foo value...")
    delay(2_000)
    println("Waiting for foo value done!")
    return "Foo"
}

suspend fun initA() {
    println("Waiting for A...")
    delay(1_000)
    println("Waiting for A done!")
} 
suspend fun initB() {
    println("Waiting for B...")
    delay(3_000)
    println("Waiting for B done!")
}
j

Joffrey

08/11/2022, 2:57 PM
Exactly
n

Nino

08/11/2022, 2:58 PM
Thanks a lot ! 🙂
3 Views