1

I have an observable object and I want to emit a default element after some time has passed (a timeout) while keeping the stream still open to emit new values in the future. How can I do this?

I attempted to do this by doing a merge of the original stream with another stream that debounces the original one while mapping the debounced value to the default that I want.

Pseudocode:

defaultDebounced = originalStream.debounce(time).map({x -> myDefaultValue})
myStream = rx.merge(originalStream, defaultDebounced)

though I don't know if I would run into some border cases like the following in which the original stream emits an item just as the timeout triggers and by chance, the default value gets emitted afterwards.

original:  ----A----B----------------------C------------
debounced: -----------------------<timeout>X------------
merged:    --------------------------------CX-----------

Also, there's the downside that the first observable has to emit at least one item in order for debounce to emit the default value.

Note: I would like to know the proper rx way to do it, regardless of the implementation, but just in case I'm working on RxSwift.

Gonzalo
  • 3,674
  • 2
  • 26
  • 28
  • It's bad to re-use the original stream like that - it's creating two subscriptions. Like Highlander, there can only be one. – Enigmativity Jul 06 '20 at 01:38

1 Answers1

3

What I finally did was:

originalStream.flatMapLatest({x -> 
    return Observable.timer(30, scheduler: MainScheduler.instance)
        .map{_ -> defaultValue}
        .startWith(x)
})
Gonzalo
  • 3,674
  • 2
  • 26
  • 28