Skip to content

animationFrameScheduler stops working unexpectedly #7018

Open
@EoinGriffin-AI

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

7.xIssues and PRs for version 7.x8.xIssues and PRs for version 8.xbugConfirmed bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions