Bug 253423

Summary: Regression(248952@main) setInterval and setTimeout order isn't respected when timeout is 0
Product: WebKit Reporter: Kaiido <tristan.fraipont>
Component: WebCore Misc.Assignee: Chris Dumez <cdumez>
Status: RESOLVED FIXED    
Severity: Normal CC: ahmad.saleem792, ap, cdumez, heycam, Hironori.Fujii, rniwa, sam, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=221124
https://bugs.webkit.org/show_bug.cgi?id=258135
Attachments:
Description Flags
Test case none

Description Kaiido 2023-03-05 18:27:43 PST
Created attachment 465310 [details]
Test case

Online test case: https://jsfiddle.net/7g5f0cLz/
1. Queue a callback using setInterval(cb1, 0);
2. Queue a callback using setTimeout(cb2, 0);

The callback queued through setTimeout() is executed before the one queued through setInterval().
You can see this StackOverflow answer of mine https://stackoverflow.com/a/75646343/3702797 for a walk-through of the specs showing how this behavior is wrong. Basically, with the same ms value, the order should be respected.

Passing another ms value than 0 will make it behave normally.
Comment 1 Ahmad Saleem 2023-03-05 18:58:06 PST
I am able to reproduce this on WebKit ToT (261247@main) and also Chrome Canary 113 also show incorrect results:

setTimeout()
setInterval()

Only Firefox Nightly 112 is giving 'Expected' result.
Comment 2 Kaiido 2023-03-06 18:49:21 PST
> Chrome Canary 113 also show incorrect results

Yes, this certainly comes from https://bugs.webkit.org/show_bug.cgi?id=221124 which removed the clamping of setTimeout( ,0) to 1ms, following what Chrome was going to do to.  
They've got the same issue and it's been reported at https://crbug.com/1421612 I guess @Wanming.Lin might chime in here too. I'll mention this issue in the CRBUG too since they seem very related.
Comment 3 Radar WebKit Bug Importer 2023-03-10 15:44:11 PST
<rdar://problem/106576260>
Comment 4 Cameron McCormack (:heycam) 2023-03-10 15:47:39 PST
Maybe we can make it so that setInterval(..., 0) will fire the callback immediately (i.e. honoring the 0ms) the first time, and at the clamped 1ms interval afterwards?
Comment 5 Chris Dumez 2023-05-30 12:05:19 PDT
Pull request: https://github.com/WebKit/WebKit/pull/14499
Comment 6 EWS 2023-05-30 15:14:12 PDT
Committed 264701@main (09e6c5eb406c): <https://commits.webkit.org/264701@main>

Reviewed commits have been landed. Closing PR #14499 and removing active labels.
Comment 7 Fujii Hironori 2023-06-12 20:37:50 PDT
fast/dom/Window/setInterval-setTimeout-zero-ordering.html is flaky.
https://results.webkit.org/?suite=layout-tests&test=fast%2Fdom%2FWindow%2FsetInterval-setTimeout-zero-ordering.html