The default implementation of setTimeout can only accept values within the range of positive signed 32-bit integers. Passing a timeout greater than (2^31)-1 milliseconds (0x7FFFFFFF) yields a TimeoutOverflowWarning and causes the runtime to ignore the specified timeout, assuming a value of 1ms (which by the way seems a dangerous default, I would have opted for using the maximum supported value or straight out throw an error).
This unexpected behavior is not documented in the README, but rather than documenting this quirk of the runtime I'd like to propose a solution: instead of relying on the bare setTimeout, delay
could use a wrapped version of it. Something like this:
const maxSupportedTimeout = 0x7fffffff;
type TimeoutContext = { id: ReturnType<typeof setTimeout> };
const defaultSetTimeout = (
callback: (...args: any[]) => void,
ms: number,
timeoutContext?: Partial<TimeoutContext>
): TimeoutContext => {
timeoutContext = timeoutContext || { id: undefined };
if (ms > maxSupportedTimeout) {
timeoutContext.id = setTimeout(
defaultSetTimeout,
maxSupportedTimeout,
callback,
ms - maxSupportedTimeout,
timeoutContext
);
} else {
timeoutContext.id = setTimeout(callback, ms);
}
return timeoutContext as TimeoutContext;
};
const defaultClearTimeout = (timeoutContext: TimeoutContext) =>
clearTimeout(timeoutContext.id);
The timeoutContext is passed by reference, therefore each time defaultSetTimeout
gets called the timeout id gets updated, so that defaultClearTimeout
can always access the most recent value.
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too