我正在创建一个文本识别应用程序,我希望只有在给定持续时间内结果不变时,流才会发出值。此外,如果在一定时间内没有发出任何值,则拒绝以前的值。
这可能有效(我没有测试它(。它依赖于定期到来的新值流,因为它只在新值到来时检查持续时间。如果一个值进入,而在很长一段时间内没有其他值,那么在后续项到达之前,它不会发出。
fun <T: Any> Flow<T>.filterToHeldTime(duration: Long): Flow<T> {
var value: T? = null
var changeTime = 0L
return transform { newValue ->
value?.let {
if (System.currentTimeMillis() - changeTime >= duration) {
emit(it)
}
}
if (newValue != value) {
value = newValue
changeTime = System.currentTimeMillis()
}
}.distinctUntilChanged()
}
如果你想支持一个可以为null的类型,你必须引入一个布尔值来跟踪第一个值是否已经收到。
编辑:也许这会奏效。它不依赖于在决定发射之前等待下一个值。如果值在指定的持续时间内保持不变,它会立即急切地发出值。
fun <T : Any> Flow<T>.filterToHeldTime(duration: Long): Flow<T> = channelFlow {
var value: T? = null
var delayedSendJob: Job? = null
collect { newValue ->
if (newValue != value) {
value = newValue
delayedSendJob?.cancel()
delayedSendJob = launch {
delay(duration)
send(newValue)
}
}
}
}