@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?
@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 - 1to 1. According to our code this is in order to match browser behaviour.Browser timers are specced unlike ours - the DOM spec coerces the
timeoutto 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:
Logs
1, 2in 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:
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:
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: