简体   繁体   English

kotlin 协程 runBlocking 和 stateIn 的问题

[英]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!我希望main的 function 仅在 100 毫秒内完成(等待第一次发射),但是当所有项目发射时会发生第二次打印(大约需要 100 * 100 毫秒)并且还会打印最后一项而不是第一个!

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.这是您使用runBlocking时的预期行为,因为runBlocking在其所有子作业完成之前不会返回。

In other words, the numbers property won't return a value until the entire flow has terminated.换句话说,在整个流程终止之前, numbers属性不会返回值。 This is because calling stateIn(scope) launches a job inside the scope that collects all the items from the flow.这是因为调用stateIn(scope)会在 scope 中启动一个作业,该作业会从流中收集所有项目。 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.如果你想让numbers流与你的main function 同时发出值,你需要使用 scope 两个函数可以一起运行。 For example, you could call runBlocking in the main function, and pass the scope as a receiver for the numbers property:例如,您可以在main function 中调用runBlocking ,并将 scope 作为numbers属性的接收器传递:

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")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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