Skip to content

Run the work loop between timers in the timer mock - #58966

Open
motiz88 wants to merge 1 commit into
mainfrom
export-D124119880
Open

motiz88 wants to merge 1 commit into
mainfrom
export-D124119880

Conversation

@motiz88

@motiz88 motiz88 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Summary:
advanceTimersByTime fired every timer due in the window first and ran their callbacks afterwards, in one work loop at the end. That is not what an idle event loop does over that much time: per the HTML timer initialization steps, each timer's task runs when it becomes due, a repeating timer is re-armed only after its callback has run, and timers scheduled by a callback can come due before later ones. Tests could not observe a callback running at its due time, and a timer implementation that re-arms after the callback (as the spec says) could not be tested at all, because its next fire would only be scheduled after the whole advance.

Here, the mock fires one timer at a time and runs the work loop after each one, for both advanceTimersByTime and runAllTimers. NativeFantom.advanceTimers / runAllTimers become advanceTimersToNextDue (fires the earliest timer due within the window and returns the time left) and runNextTimer; the loop and its 100,000-fire safety bound move to TimerMock.js.

Changelog: [Internal]

Differential Revision: D124119880

Summary:
`advanceTimersByTime` fired every timer due in the window first and ran their callbacks afterwards, in one work loop at the end. That is not what an idle event loop does over that much time: per the [HTML timer initialization steps](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timer-initialisation-steps), each timer's task runs when it becomes due, a repeating timer is re-armed only after its callback has run, and timers scheduled by a callback can come due before later ones. Tests could not observe a callback running at its due time, and a timer implementation that re-arms after the callback (as the spec says) could not be tested at all, because its next fire would only be scheduled after the whole advance.

Here, the mock fires one timer at a time and runs the work loop after each one, for both `advanceTimersByTime` and `runAllTimers`. `NativeFantom.advanceTimers` / `runAllTimers` become `advanceTimersToNextDue` (fires the earliest timer due within the window and returns the time left) and `runNextTimer`; the loop and its 100,000-fire safety bound move to `TimerMock.js`.

Changelog: [Internal]

Differential Revision: D124119880
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 9, 2026
@facebook-github-tools facebook-github-tools Bot added p: Facebook Partner: Facebook Partner labels Oct 9, 2026
@meta-codesync

meta-codesync Bot commented Oct 9, 2026

Copy link
Copy Markdown

@motiz88 has exported this pull request. If you are a Meta employee, you can view the originating Diff in D124119880.

This branch has not been deployed

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant