-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Confused setTimout behaviour in NodeJS #46596
Comments
That's working as designed. From the timers documentation:
The WHATWG spec leaves some wiggle room ("This API does not guarantee that timers will run exactly on schedule") so some variation between implementations is to be expected. Node could be changed to behave more like Chrome but there's a non-zero risk of ecosystem fallout. |
@bnoordhuis Thanks for clarifying it Ben! for example: setTimeout(() => {
console.log('calling 1st timeout')
}, 3)
setTimeout(() => {
console.log('calling 2rd timeout')
}, 2) in node 14 it will be: calling 1st timeout
calling 2rd timeout however in node 18 it will be calling 2rd timeout
calling 1st timeout I guess there is no practical use case for the above in any event but just something I found interesting and not really documented somewhere. |
I am in favor of changing the behavior for 0 to behave as chrome does. Besides that, I would actually like to deviate from the spec when it comes to exceeding |
I agree completely that the behavior in the spec is not good, but I don't think we should deviate from it. |
Changing the timing of this stuff always carries a non-zero risk of breaking apps. While the inconsistency with browsers is unfortunate, I agree that we likely shouldn't change it. |
Perhaps someone wants to open a pull request and run it through citgm to get a feel for how bad it impacts the ecosystem? |
I don't think we should deviate from the spec. I could be convinced if this would cause no ecosystem breakage. |
Wanna point out the code blow in chrome browser does not set the delay to 1 which is a little bit surprising. setTimeout(() => {
console.log('finished')
}, 100000000000000) |
Is it possible to discuss the above in tsc agenda meeting as well (despite it is mentioned in the doc - The callback will likely not be invoked in precisely delay milliseconds. Node.js makes no guarantees about the exact timing of when callbacks will fire, nor of their ordering. The callback will be called as close as possible to the time specified.), looks like there is a behaviour change in node v18.x in comparison to previous node versions but it is not being mentioned in the doc history. |
There is no behavior change, timers are weird for this and they highly depend on the event loop phases, the startup time of Node.js and the underlining operating system. |
The standard itself does actually not provide any restrictions when it comes to zero being handled as one or the maximum value being a 32-bit signed integer. The latter seems to be a historic implementation detail of browsers while not ending in the spec itself. I suggest to split the discussion into three parts:
|
For the record, node follows what browsers did ca. 2011: nodejs/node-v0.x-archive#593 (comment) |
The 1 ms minimum has recently been removed from chrome: https://chromestatus.com/feature/4889002157015040 Seems like the browsers do improve the situation minimally and as such, we could also do that. It would of course be a breaking change that would have to be communicated. |
Partially addressed nodejs#46596 to keep the consistency of the warning message for TIMEOUT_MAX number as the negative number will be set to 1.
Partially addressed nodejs#46596 to keep the consistency of the warning message for TIMEOUT_MAX number as the negative number will be set to 1.
Partially addressed nodejs#46596. To keep the consistency of the warning message for TIMEOUT_MAX number As the negative number will be set to 1.
Hi Ruben @BridgeAR 👋 thank you for your thoughts and reply! I followed the link to the spec but didn't find the reference for this one 🤔 would you be able to elaborate:
From what I understand, nodejs will set the negative numbers or 0 or |
Partially addressed nodejs#46596. To keep the consistency of the warning message for TIMEOUT_MAX number As the negative number will be set to 1.
We briefly discussed this during the TSC meeting but we did not have a sufficient audience to provide the counter perspective. From my perspective, and I believe it's echoed by @jasnell, we already don't follow the standard today and trying to make this change doesn't meaningfully change that. In addition, the behaviour of timers is more problematic in a server environment as compared to the browser. Anecdotally I've also seen reliance on this behaviour — as silly as that is — out in the wild and I'm not sure as to the value of a semver major change here. I would be very clear -1 on this change or other changes to try & align with the spec without some clear evidence that it would be net-positive for the project. |
So Chrome “fixed” their lower-end clamping to 1ms? Is that the deal here? If so Node.js should probably get rid of that too. It was confusing and there are probably more bugs that exist because of that behavior than will exist when removing that behavior. |
Version
14, 18
Platform
22.2.0 Darwin Kernel arm64
Subsystem
No response
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
No response
What is the expected behavior?
Would expect the second time to be called first
What do you see instead?
The first time out is called then the second timeout in NodeJS
Additional information
No response
The text was updated successfully, but these errors were encountered: