1

I want to handle clicks in such a way that they are ignored as long as I'm doing processing of some click that occurred.

I thought I could do it by utilizing the backpressure, like this:

private val clicks = PublishProcessor.create<Unit>()

// ...

clicks
    .onBackpressureDrop()
    .concatMapSingle(::handleClick, 0)

But this throws an error, because there's a requirement that concatMapSingle needs to prefetch at least one item, which makes it queue the click and process it immediately after I'm done processing, which is not what I want. I want to process the click only if there is no processing happening at the moment.

Is there some other operator I could use to achieve the desired effect?

arekolek
  • 9,128
  • 3
  • 58
  • 79
  • 1
    why not simply disable the button before you start processing the click? – Tim Oct 24 '18 at 10:45
  • There's no disabled state in the UI, so the user wouldn't notice any difference. Also, I never said it was a button ;) – arekolek Oct 24 '18 at 11:13
  • any other clickable then. If there is no disabled state, there is no difference between disabling the clicks and ignoring them, is there? – Tim Oct 24 '18 at 11:27
  • I think there could be a race condition when disabling clicks in UI, that is not there when ignoring clicks. Also, why involve the view (adding extra method to MVP contract), if I can handle it in the presenter this easily. – arekolek Oct 24 '18 at 11:39

1 Answers1

4

Using flatMapSingle instead of concatMapSingle does the trick, as suggested by akarnokd on GitHub:

flatMap will only fetch the next upstream item if the current one actually completed

The last parameter is maxConcurrency, specifying the maximum number of active subscriptions to the SingleSources:

clicks
    .onBackpressureDrop()
    .flatMapSingle(::handleClick, false, 1)

In this instance, flatMapSingle subscribes to those Singles sequentially, so it doesn't change the semantics I got from concatMapSingle.

arekolek
  • 9,128
  • 3
  • 58
  • 79