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 ?
CodePudding user response:
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")
}