【问题标题】:When kotlin flow issues duplicate data 3 times, why does it only receive 2 times in collection?当 kotlin flow 发出 3 次重复数据时,为什么它在 collection 中只收到 2 次?
【发布时间】:2021-02-18 08:15:21
【问题描述】:

我对 collect 函数进行了基本测试以学习 kotlin 流程。

测试的时候有什么奇怪的,所以我留下了一个帖子

在流程块中,存在输入 3 个相同的发射值的情况。 然后,将收集到的数据输出到日志中。

代码内容:

   flow {
    emit(1)
    emit(1)
    emit(2)
    emit(2)
    emit(2)
    emit(2)
    emit(3)
    emit(3)
    emit(4)
    emit(4)
    emit(4)
    emit(5)
}.collect {
    println(it)
}

结果:

1
1
2
2
3
4
4
5

代码执行emit(2) 4 次和emit(4) 3 次。 但collect 只包含24 2 次。

你知道为什么会这样吗?

【问题讨论】:

  • 我认为你错了。在代码中,流和收集器在同一个协程中运行,因此它们必须按顺序工作。如果其中一个被暂停,它们会互相暂停。

标签: kotlin kotlin-coroutines kotlin-flow


【解决方案1】:

如果日志是 LogCat(又名 Android),那是因为 LogCat 本身会过滤掉重复的行。 (也可能是 pidcat,但我很确定它是 LogCat)。这一切都基于所使用的标签。

例如,我有一个用于 Timber 的自定义 DebugTree,它在其中添加行号作为标签名称的一部分。

如果我这样做:

flow.emit(0)
flow.emit(0)
flow.emit(0)
flow.emit(0)
flow.emit(0)

我会看到

MyClass:1    D    0
MyClass:2    D    0
MyClass:3    D    0
MyClass:4    D    0
MyClass:5    D    0

如果我没有使用标签中的行号:

MyClass    D    0
MyClass    D    0

LogCat 看到标签和消息是相同的,因此删除了重复项。

此外,这取决于“流程”使用的是哪个实现。例如,如果它使用 StateFlow,则不会发出重复值。

@Test
fun `test flow`() = runBlockingTest {
    val flow = MutableStateFlow(0)

    val job = TestCoroutineScope().launch {
        flow.collect { println(it) }
    }

    flow.emit(0)
    flow.emit(0)
    flow.emit(0)
    flow.emit(0)
    flow.emit(1)
    flow.emit(2)
    flow.emit(2)
    flow.emit(3)
    flow.emit(3)
    
    job.cancel()
}

结果:

0
1
2
3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 2022-12-15
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2021-08-28
    相关资源
    最近更新 更多