3

It seems that debounceTime ignores inner calls to it's subjects next method:

var subject: Subject<number> = new Subject<number>();

subject.pipe(
    tap((a) => console.log("tab:" + a)), 
    debounceTime(300), 
).subscribe((a) => {
    console.log(a);
    subject.next(100)
});

subject.next(19);
subject.next(20);

the code above should create an infinite loop - but it does not:

tab:19
tab:20
20
tab:100

if I add a delay(1) to the pipe it works as expected:

subject.pipe(
    tap((a) => console.log("tab:" + a)), 
    debounceTime(300), 
    delay(1)
).subscribe((a) => {
    console.log(a);
    subject.next(100)
});

am I missing something?

Edit: added an example: https://typescript-fbt2mn.stackblitz.io

msanford
  • 11,803
  • 11
  • 66
  • 93
user1859022
  • 2,585
  • 1
  • 21
  • 33
  • 2
    This usage looks like an edge-case to me, I never had to do something similar. It looks RxJS "resets" the debounce time after it notified the Observers, which is a synchronous operation since an older version of RxJS. Let me reverse the question, what behavior are you trying to achieve and do you have any problems with your workaround? – Tamas Hegedus Apr 24 '18 at 12:25
  • 3
    Seems related to https://github.com/ReactiveX/rxjs/pull/3218 – cartant Apr 24 '18 at 12:44

1 Answers1

5

This type of issues where something seems to be broken and that can be magically fixed with using delay(0) or setTimeout usually means that you're expecting RxJS to behave asynchronously all the time while in fact it usually works synchronously unless forced to do otherwise.

And that's exactly your case.

Btw, a little more elegant way is using the observeOn operator with an async scheduler that should be more performance efficient then delay(1).

import { async } from 'rxjs/scheduler/async';

var obs = Observable.of(1, 2, 3);
var subject: Subject<number> = new Subject<number>();

subject.pipe(
    tap((a) => console.log("tab:" + a)), 
    debounceTime(300),
    observeOn(async),
).subscribe((a) => {
    console.log(a);
    subject.next(a+1)
});

See you updated demo: https://stackblitz.com/edit/typescript-tsek9s?file=index.ts

Edit: This behavior has probably changed in RxJS 6: https://github.com/ReactiveX/rxjs/pull/3218

martin
  • 93,354
  • 25
  • 191
  • 226