简体   繁体   中英

problem with kotlin coroutine runBlocking and stateIn

import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking

val numbers: StateFlow<Int> = (1..100).asFlow()
    .onEach { delay(100) }
    .let {
        runBlocking {
            it.stateIn(this)
        }
    }

fun main(){
    println("hello")
    println(numbers.value)
    println("bye")
}

I expect that main function finish only in 100ms (wait for first emission) but second print happens when all items emitted (takes about 100*100 ms) and also prints last item instead of first one!

am I missing something or it is a bug?

That's expected behaviour when you use runBlocking , because runBlocking won't return until all of its child jobs have completed.

In other words, the numbers property won't return a value until the entire flow has terminated. This is because calling stateIn(scope) launches a job inside the scope that collects all the items from the flow. You can see where this happens in the source code .

If you want to allow the numbers flow to emit values concurrently with your main function, you'll need to use a scope in which both functions can run together. For example, you could call runBlocking in the main function, and pass the scope as a receiver for the numbers property:

val CoroutineScope.numbers: StateFlow<Int> get() = (1..100).asFlow()
    .onEach { delay(100) }
    .let {
        it.stateIn(this)
    }

fun main() = runBlocking {
    println("hello")
    println(numbers.value)
    println("bye")
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM