# Timers

> How Elide supports setTimeout, setInterval, setImmediate and queueMicrotask: Node Timeout objects instead of numbers, and callback order at checkpoints.

`setTimeout`, `setInterval`, `setImmediate`, their `clear*` counterparts, and `queueMicrotask` are globals that follow
the [HTML timer](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) API.

## Example

```js
// htmltimers.mjs
setTimeout(() => {
  const order = [];
  setTimeout(() => order.push("timeout"), 0);
  setImmediate(() => order.push("immediate"));
  Promise.resolve().then(() => order.push("promise"));
  queueMicrotask(() => order.push("microtask"));
  process.nextTick(() => order.push("nextTick"));
  setTimeout(() => console.log(order.join(" ")), 20);
}, 0);

let runs = 0;
const interval = setInterval(() => {
  if (++runs === 2) {
    clearInterval(interval);
    console.log("interval ran", runs, "times; hasRef:", interval.hasRef());
  }
}, 5);
```

`elide run htmltimers.mjs` prints:

```text
interval ran 2 times; hasRef: true
nextTick promise microtask immediate timeout
```

## Differences from browsers

- Timers return Node `Timeout` or `Immediate` objects, not numbers, with `ref()`, `unref()`, `hasRef()`, and
  `refresh()` (`Timeout` only).
- String handlers are not supported; the callback must be callable.
- `setTimeout(callback)` without a delay prints `TimeoutNaNWarning` before running the callback; pass `0`.
- At a checkpoint, callbacks run in this order:
  1. `process.nextTick`
  2. Promise and `queueMicrotask` callbacks, in enqueue order
  3. `setImmediate`
  4. Zero-delay timers

<!-- api-reference:start 581f63d8af5c -->
## Reference

**Status:** Full · Not measured
<!-- api-reference:end -->
