Skip to content

Timers default at 1 due to historical reasons #20596

Description

@benjamingr

@nodejs/timers

Some context: I'm helping maintain lolex which is a fake timer library. Currently @SimenB is working on porting jest to use lolex which means we're running into a bunch of edge cases internally. Both are large-ish Node.js packages with >1M weekly NPM downloads.

We currently set timers that exceed 2 ** 31 - 1 to 1. According to our code this is in order to match browser behaviour.

Browser timers are specced unlike ours - the DOM spec coerces the timeout to a Uint32 which converts overflows to 0 rather than 1.

This is more in tune of what browsers actually do though there are no relevant tests in the webidl test suite so we can't really know what browsers do, though:

setTimeout(() => console.log(1), Infinity);
setTimeout(() => console.log(2), 0);

Logs 1, 2 in Chrome and Node, except Node logs a pretty confusing warning saying the timeout was set to 1 (since we set timeouts < 1 to 1).

This is another difference in the web behavior which allows setting the timeout to 0 but automatically sets it to 5 once it's been nested four times:

Timers can be nested; after five such nested timers, however, the interval is forced to be at least four milliseconds.

I asked @bnoordhuis who committed the code to Node and he did this in order to match browsers which makes a lot of sense since we don't allow timers to be 0. Moreover, actual Chrome also doesn't allow 0 as a timeout:

setTimeout(() => console.log(2), 1);
setTimeout(() => console.log(1), 0);

Logs 2, 1 in both Chrome and Node. (Changing 1 to 2 fixes this).


My assumption here is that Chrome deviates from the timers spec due to historical reasons (websites not working or something similar). The question is:

  • Do we like our current behaviour? (Which aligns with Chrome and both deviate from the spec)
  • Does anyone know why Chrome behaves this way?

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussIssues opened for discussions and feedbacks.timersIssues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions