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).
| Function | Returns | Notes |
|---|---|---|
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?) | undefined | Unknown / non-numeric ids are silent no-ops. |
clearInterval(id?) | undefined | Same. |
clearImmediate(id?) | undefined | Same. |
queueMicrotask(callback) | undefined | callback 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/setIntervaldo not accept a code-string handler.Timeout/Immediateobjects (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.