【问题标题】:Flow that emits the last value periodically, and when a new value arrives定期发出最后一个值的流,当一个新值到达时
【发布时间】:2026-01-24 20:35:01
【问题描述】:

我想创建一个 Kotlin 协程 Flow,它在何时发出值

  1. 它们会改变,并且
  2. 自上次更改或上次发出后每隔 x 持续时间定期发出最后一个可用值。

【问题讨论】:

    标签: kotlin kotlin-coroutines


    【解决方案1】:

    这似乎可行——每次新值到达时,transformLatest 都会取消任何以前的 lambdas 并启动一个新值。所以这种方法会发出,然后继续周期性地发出,直到有新值到达。

    flow.transformLatest { value ->
      while(currentCoroutineContext().isActive) {
        emit(value)
        delay(x)
      }
    }
    

    【讨论】:

    • 您可以放弃isActive 检查。取消也一样。
    • 是的,但是while 没有条件的循环让我感到厌烦。我喜欢显式检查提供的额外注意事项。
    【解决方案2】:

    您可以创建一个定期发射的Flow,然后使用combine。每次合并这些值时,您实际上只是传递了您感兴趣的原始 Flow 的当前值。

        // This is the main flow you are interested in. This uses
        // a Flow builder just as a simple example but this could
        // be any kind of Flow, like a (Mutable)StateFlow.
        val emitter = flow {
            emit("Your data")
            // ...
        }
        // This just serves as a timer.
        val timer = flow {
            while (currentCoroutineContext().isActive) {
                emit(Unit)
                delay(500)
            }
        }
        // This will emit whenever either of the Flows emits and 
        // continues to do so until "emitter" stops emitting.
        combine(
            emitter,
            timer
        ) {  value, ticker ->
            // Always just return the value of your
            // main Flow.
            value
        }
    

    【讨论】:

    • 这将在最后一次发射完成后停止
    • @ShawnThye 当然,但假设那里 最后一个“发射”。我在这里使用了一个流程构建器,只是为了提供一个独立的示例,但大概我们正在谈论从另一个永远不会“完成”的流程开始。如果他们从一个确实完成的流程开始,也许他们希望整个流程也完成。但这一切都归结为他们正在寻找的东西。我个人目前已经在将我建议的“ticker”流与 MutableStateFlow 结合使用时使用此解决方案。
    • 是的,我认为对于他的情况,他需要使用 MutableShareFlow 或 MutableStateFlow 取决于他的范围:)
    最近更新 更多