Timers

Elide installs the seven canonical timer globals on globalThis. Four are defined by the [HTML Standard][html-timers] (setTimeout, clearTimeout, setInterval, clearInterval); queueMicrotask is defined by [HTML §queueMicrotask][html-microtask]; setImmediate and clearImmediate are provided for Node compatibility. These functions are also re-exported from the node:timers module (with a Promise-based node:timers/promises variant).

[html-timers]: https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers [html-microtask]: https://html.spec.whatwg.org/multipage/webappapis.html#dom-queuemicrotask
FunctionReturnsNotes
setTimeout(handler, delay?, ...args)number (id)delay coerced to number; NaN / non-finite / negative → 0. Fires once.
setInterval(handler, delay?, ...args)number (id)Same coercion; fires repeatedly until cleared.
setImmediate(handler, ...args)number (id)Fires after the current microtask checkpoint, before any zero-delay setTimeout.
clearTimeout(id?)undefinedUnknown / non-numeric ids are silent no-ops.
clearInterval(id?)undefinedSame.
clearImmediate(id?)undefinedSame.
queueMicrotask(callback)undefinedcallback must be callable; throws TypeError otherwise. Enqueued onto the microtask queue.
handler may be any callable. String handlers (HTML legacy eval-style) are not supported.

Ordering

Within a single event-loop turn:

1. Microtasks (queueMicrotask, Promise.then) drain to completion. 2. setImmediate callbacks fire in FIFO order. 3. Due setTimeout / setInterval callbacks fire in deadline order.

A handler scheduling a new timer is observed on the next turn. A handler calling clear* on an id whose timer has not yet fired cancels it synchronously.

Delay semantics

delay is interpreted in milliseconds, coerced via the standard ToNumber algorithm, then clamped:
  • NaN, Infinity, negatives, and non-finite values → 0.
  • Values exceeding ~292 years saturate at the scheduler's maximum to avoid overflow in deadline arithmetic. (Practically unreachable.)

Actual fire-time has no upper bound: a busy event loop or long-running synchronous handler postpones subsequent timers. The HTML clamp on nested timeouts (≥ 4 ms after five levels of nesting) is not applied — Elide follows Node's behavior here.

Threading and re-entrancy

Each realm has its own scheduler; timers from one realm cannot fire on another. The scheduler uses a monotonic clock (System.nanoTime) so wall- clock adjustments do not affect deadlines. Handlers may freely call setTimeout, clearTimeout, etc. from inside a firing callback — the scheduler snapshots the due set before firing and re-checks cancelled flags before each reschedule.

Errors thrown from handlers

An uncaught exception in a timer callback is reported via the realm's diagnostic stream and does not stop the loop or cancel sibling timers. This matches the HTML spec ("an uncaught exception is reported, the timer keeps firing").

Limitations

  • setTimeout / setInterval do not accept a code-string handler.
  • Timeout / Immediate objects (Node's reference-typed return values with .ref() / .unref() / .refresh()) are not implemented; the return value is a numeric id only.
  • There is no process.binding('timer_wrap') surface.