Home > database >  Why these two Kotlin coroutines functions are not the same?
Why these two Kotlin coroutines functions are not the same?

Time:02-04

Main function:

fun main() = runBlocking {
    val channel = Channel<Int>()
    foo(channel)
    for (y in channel) println(y)
    println("Done!")
}

This works:

fun CoroutineScope.foo(channel: Channel<Int>) {
    launch {
        for (x in 1..5) channel.send(x * x)
        channel.close()
    }
}

This does not work (it blocks on channel send):

suspend fun foo(channel: Channel<Int>) = coroutineScope {
    launch {
        for (x in 1..5) channel.send(x * x)
        channel.close()
    }
}

Why?

CodePudding user response:

As stated in the documentation of coroutineScope:

This function returns as soon as the given block and all its children coroutines are completed

So, writing coroutineScope { launch { something() }} is equivalent to just something(), because it waits for the launch's completion. This, in turn, means that your second version of foo returns only when the loop is completed and the channel closed.

On the other hand, using just launch launches an async task, so the code after foo() can work concurrently with it.

Actually, if you inline foo() in both cases, you will realise that the launch-ed coroutine is delimited by runBlocking's scope in the first case, and by coroutineScope's scope in the second case.

  • Related