Skip to content

animationFrameScheduler with delay causes incorrect behavior (and exception) #6891

@ajafff

Description

@ajafff

Describe the bug

If AnimationFrameScheduler#schedule is used with a delay > 0, the action is scheduled as AsyncAction. Executing the action takes the same code path as AnimationFrameAction.
So if the AsyncAction executes while AnimationFrameActions are scheduled, it executes those too, which is too early as the browser is not yet preparing the next frame.

With the fix in #6889 it will throw an error, when rAF tries to execute the actual AnimationFrameActions, but the queue is already empty:

Uncaught TypeError: Cannot read properties of undefined (reading 'execute')
      at AnimationFrameScheduler.flush (src\internal\scheduler\AnimationFrameScheduler.ts:24:27)
      at C:\code\rxjs\src\internal\scheduler\AnimationFrameAction.ts:21:121

Expected behavior

AsyncAction to be handled separately. Ideally we could use asyncScheduler.schedule(...) instead of super.request/recycleAsyncId.

Reproduction code

animationFrameScheduler.schedule(() => console.log('async'), 1);
animationFrameScheduler.schedule(() => console.log('animation frame'));

Reproduction URL

No response

Version

7.5.5

Environment

No response

Additional context

I could try to fix this, but I'm not sure how to test this properly. The code above flaky, because the timeout of 1ms is not guaranteed to be executed before the next animation frame. I guess I could mock the relevant animationFrameProvider

asapScheduler uses similar code, but seems not to be affected, because timeouts will never be executed before microtasks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions