Hi everyone, I'm investigating an issue with `debo...
# reaktive
o
Hi everyone, I'm investigating an issue with
debounce
in iOS, for some reason is NOT waiting the
timeout
Copy code
@Test
fun `'debounce' using Main scheduler works`() {
    val timeout = 10L
    val time = getTimeMillis()
    val wasCalled = AtomicBoolean(false)

    observableOf(1, 2, 3, 4, 5)
        .debounce(timeout, mainScheduler)
        .subscribe { value ->
            val elapsed = getTimeMillis() - time
            assertTrue("Should have passed more than $timeout millis, but was $elapsed") { elapsed >= timeout }
            assertEquals(5, value)

            wasCalled.value = true
        }

    await(2*timeout.toInt())
    assertTrue("`subscribe` was not called") { wasCalled.value }
}
The test fails
kotlin.AssertionError: Should have passed more than 10 millis, but was 1
But it works with
ioScheduler
and
computationScheduler
,
also if
delay
is used instead of
debounce
it works as well. PS: The
await
functions just runs the current Loop:
Copy code
private fun await(millis: Int) {
    NSRunLoop.currentRunLoop.runUntilDate(NSDate.dateWithTimeInterval(millis.toDouble()/1000.0, NSDate.now))
}
a
Hello, if I'm not missing something the subscribe block should be called with a single value
5
almost immediately after subsription. The output looks correct.
This is your case:
o
Hi, thanks for the response, according to the doc (and the bubble diagram) there's an initial delay
a
Where do you see an initial delay?
o
a
You mean the delay between first blue "1" and its emission?
o
The first element is emitted after the
timeout
as well
Yes
a
But in your case the second element is emitted straightaway which "overrides" the first one
o
Yes, the seconds elements "resets" the timer, but it should be emitted after the timeout elapsed (This is what I expect)
a
No, as soon as items are emitted by upstream and the time between emissions is less than timeout, nothing will be emitted
Basically every emission from upstream resets the timer. Emission to downstream is performed when the timer reaches timeout.
Or when upstream completes
o
Exactly, and in my case is not when it reaches the timeout, but immediately
a
I don't understand
o
In any case, whatever element is emitted, it should be after the timeout (at least)
a
No, because upstream complets
This forces debounce to emit
o
AHhh I see
Good point, let me rewrite the test case
a
Yep, something like:
Copy code
observable<Int> { (1..5).forEach(it::onNext) }
👀 1
Without completion it should emit the last value after timeout
o
👏 Indeed
Thanks
👍 1
a
You are welcome