How would you create a flow that emits values when...
# coroutines
r
How would you create a flow that emits values when they change and periodically emits the last value available, every x duration since the last change or emit? So far what I've got is this:
Copy code
flow.transformLatest { value ->
  while(currentCoroutineContext().isActive) {
    emit(value)
    delay(x)
  }
}
s
A probably naive approach: I'd
combine
a timer (for the "periodical every x seconds part"), and my actual flow, like this:
Copy code
// the timer
val timer = (0..Int.MAX_VALUE).asSequence().asFlow().onEach { delay(1_000) }

// your other flow
val other = flow {
    emit("A")
    delay(1500L)
    emit("B")
    delay(1500L)
    emit("C")
}

// combine them
launch {
    combine(timer, other, ::Pair)
        .collect { (timer, other) ->
            println("bling: ${timer} | ${other}")
        }
}
Of course you can ignore / map away the received timer value, since you are probably only interested in the actual value.
r
Interesting approach, thanks. The transformLatest seems to encapsulate the logic a bit better though.
o
My first instinct would be to employ a channelFlow and upon receiving an upstream value 1. Emit the value 2. Spin up a repeating coroutine to periodically emit this value into the channel again.
r
3. Cancel all of the repeating coroutines once a new value is received.
What does it get me over the
transformLatest
approach?
o
Likely nothing