You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Flow技术问询:仅对特定true值实现防抖持留

解决方案

要实现FlowA为true时持留该状态1秒,期间忽略后续的false值,可以通过自定义Flow操作符来实现——之前的debounce方案逻辑是延迟后发射最后值,不符合持留true的需求。

自定义持留true状态的操作符

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow

fun Flow<Boolean>.holdTrueFor(duration: Long): Flow<Boolean> = flow {
    var isHoldingTrue = false
    var holdJob: Job? = null

    collect { currentValue ->
        when (currentValue) {
            true -> {
                if (!isHoldingTrue) {
                    // 首次收到true,立即发射并启动持留计时
                    emit(true)
                    isHoldingTrue = true
                    // 取消之前的持留任务(如果有)
                    holdJob?.cancel()
                    holdJob = coroutineScope {
                        launch {
                            delay(duration)
                            // 持留时间结束,允许后续更新状态
                            isHoldingTrue = false
                        }
                    }
                }
                // 持留期间收到的true,无需处理(保持当前状态即可)
            }
            false -> {
                if (!isHoldingTrue) {
                    // 非持留状态下收到false,直接发射
                    emit(false)
                }
                // 持留期间收到的false,直接忽略
            }
        }
    }

    // 收集结束时取消持留任务
    holdJob?.cancel()
}

合并Flow的使用方式

将FlowA通过自定义操作符处理后,再与FlowB合并,就能保证FlowA的true状态至少维持1秒,不会被快速的false覆盖:

combine(flowA.holdTrueFor(1000L), flowB) { aValue, bValue ->
    aValue && bValue
}.collect { combinedResult ->
    if (combinedResult) {
        doSomething()
    }
}

逻辑说明

  • 当FlowA发射true时,立即输出true,并启动1秒的延迟任务,期间标记为“持留true状态”
  • 持留状态内,FlowA发射的任何false都会被忽略,保持输出true
  • 1秒后持留状态结束,后续FlowA发射的false才会被正常输出
  • 如果持留期间FlowA再次发射true,会重置持留计时,确保true状态继续维持1秒

内容的提问来源于stack exchange,提问作者Citut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:55:30