如何解决Kotlin协程:Hot Flow持有线程
我正在尝试使用BehaviourSubject
模拟Flow
。
由于collect {}
不允许协程继续进行,因此以下示例中的代码无法正确运行:
@FlowPreview
@ExperimentalCoroutinesApi
fun main() = runBlocking {
val scope = CoroutineScope(Dispatchers.IO)
val channel = MutableStateFlow(0)
channel.value++
val flow = channel.broadcastIn(scope).asFlow()
channel.value++
flow.collect { println("First: $it") } // Code will stop executing here ...
flow.collect { println("Second: $it") } // Will not execute
channel.value++ // Wil not execute
return@runBlocking
}
输出:
First: 2
// process not exited
我不认为采用回调也应该保持线程。 问题出在哪里?
这样的问题 Flow
不会发生:
fun main() = runBlocking {
val data = listOf(1,2,3,4,5).asFlow()
data.collect { println(it) }
println("Done")
}
输出:
1
2
3
4
5
Done
我想念什么吗?
科特琳:
1.4.10
协程:1.3.9
解决方法
在两种情况下,Flow
的行为相同,您错过的是Flow.collect
暂停直到流程完成。
在冷流的情况下,在发出5个值后,它显然结束了,因此完成了执行。同时,在热流中,流的完成取决于在collect
返回后执行的代码(经典的死锁)。
如果在collect
块中异步执行launch
,则两种情况下的行为相同。但是由于StateFlow
不能通过设计“终止”,因此最终将永远等待无法发生的终止。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。