Description
Describe the bug
These operators in RxJS (7.5.4) just... stop working sometimes. What's going on? How can I fix this?
Update: I also tried this with auditTime
instead and the same issue occurs, so I believe it's more related to animationFrameScheduler
and not debounceTime
import { animationFrameScheduler, Observable, OperatorFunction } from 'rxjs';
import { debounceTime, tap } from 'rxjs/operators';
export function debounceAnimated<T>(): OperatorFunction<T, T> {
return (source$: Observable<T>) => source$.pipe(
tap(() => console.log('A')),
debounceTime(0, animationFrameScheduler),
tap(() => console.log('B')),
);
}
This operator works just fine most of the time. I see in my app that the action using this operator works correctly, and in the console I see a bunch of A's followed by a bunch of B's, as expected when the debounceTime fires.
The problem is that sometimes this operator just... breaks somehow. I get a whole bunch of A's when I perform the user action (in this case using the mouse scroll to zoom in and out of a chart), but the B's stop completely and downstream observable subscriptions stop working too. The application doesn't recover when this happens. Everything else seems to be fine, CPU usage is low, and other components that don't use this operator continue to work normally.
For a bit more context, this feature has been working fine for a few years, but a recent RxJS upgrade (we upgraded from 6.6.2 to 7.5.4 to get a necessary bugfix) broke the previous implementation of this operator and so now I'm trying to find some alternative. The previous implementation used this code, but it no longer debounces anything when written like this: debounce(() => EMPTY.pipe(observeOn(scheduler)))
I also posted this same question on StackOverflow, in case anyone wants to follow there too.
https://stackoverflow.com/questions/72916854/rxjs-debouncetime-operator-with-animationframescheduler-stops-working-unexpected
Expected behavior
debounceTime with animationFrameScheduler should continue to work indefinitely as long as there are active subscribers.
Reproduction code
In my case this code is run many times. Several Observables (maybe 10?) use this custom debounceAnimated operator and it gets his about 50 times and so logs 'A' 50 times on a single mouse scroll event. Obviously I don't want to re-render my UI 50 times, which is why I need this to work.
import { animationFrameScheduler, Observable, OperatorFunction } from 'rxjs';
import { debounceTime, tap } from 'rxjs/operators';
export function debounceAnimated<T>(): OperatorFunction<T, T> {
return (source$: Observable<T>) => source$.pipe(
tap(() => console.log('A')),
debounceTime(0, animationFrameScheduler),
tap(() => console.log('B')),
);
}
Reproduction URL
No response
Version
7.5.4
Environment
Chrome Version 103.0.5060.66 (Official Build) (64-bit)
Windows 10
Angular 13.2.6
Typescript 4.5.5
Additional context
No response
Activity