有sourceFlow
,我使用flatMapLatest
从sourceFlow
生成新的流。collect()
中没有值。此代码不打印任何内容。
fun main() {
fun createNewFlow(): MutableSharedFlow<String> = MutableSharedFlow()
runBlocking {
val sourceFlow = MutableSharedFlow<Int>()
// flow for transform
val set = mapOf(
1 to createNewFlow(),
2 to createNewFlow(),
3 to createNewFlow()
)
launch {
// get flow from set by number from sourceFlow
val res = sourceFlow.flatMapLatest { set[it]!! }
res.collect {
println(it)
}
}
launch {
sourceFlow.emit(1)
set[1]!!.emit("1")
set[1]!!.emit("1")
sourceFlow.emit(2)
set[2]!!.emit("2")
set[2]!!.emit("2")
}
}
}
如果我将flatMapLatest
更改为flatMapConcat
,我会看到1
两次,这显然是因为set[1]中的流没有完成,但我在使用flatMapLatest
时正在等待1, 1, 2, 2, 3, 3
。我的样品有什么问题?
**UPD:**我只是添加了延迟,得到了println
的结果。所以,这真的是一场代码竞赛
launch {
delay(3000)
sourceFlow.emit(1)
set[1]!!.emit("1")
set[1]!!.emit("1")
}
1条答案
按热度按时间7lrncoxx1#
正如@louis-wasserman在评论中指出的那样,这是一场竞赛(虽然不是线程不安全的数据竞赛)。
flatMapLatest
在内部collect
s(并取消)子流。默认情况下,MutableSharedFlow不会重播订阅之前的元素。因此,两个协程之间存在竞争。如果第一个协程在第二个协程调用
emit
之后成为订阅者,则不会接收任何值。您可以指定replay
参数以确保collect
调用在订阅之前接收元素。