Execute Program

JavaScript Concurrency: What's Inside a Timeout?

Welcome to the What's Inside a Timeout? lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • We've seen timers and how to clear them by passing them to clearTimeout. But when we do that, what are we actually passing to clearTimeout? What does the timer object look like?

  • Unfortunately, the answer varies by platform. In browsers, the answer is simple: timers are number IDs. Each timer gets a new ID.

  • >
    setTimeout(() => { /* do nothing */ });
    Result:
  • >
    [
    setTimeout(() => { /* do nothing */ }),
    setTimeout(() => { /* do nothing */ }),
    ];
    Result:
  • >
    typeof setTimeout(() => { /* do nothing */ });
    Result:
  • setInterval works in the same way: it returns numbers.

  • >
    const interval = setInterval(() => { /* do nothing */ });
    clearInterval(interval);
    typeof interval;
    Result:
  • When we call clearTimeout(timer), we're passing that number back to the browser. It looks up the timer by its ID and cancels it.

  • The examples and explanation above may seem strange. We said that the return value of setTimeout varies by platform, and then showed you code examples where it returns a number. That's because in browsers, setTimeout always returns a number, regardless of which browser we're using.

  • In Node, which is normally used on servers, this works differently. There, the setTimeout return might look more like this.

  • >
    setTimeout(() => { /* do nothing */ });
    Result:
  • The _ prefixes tell us that we shouldn't use these properties. All of the properties prefixed with _ are internal values used by Node.

  • The takeaway here is that there are no "user serviceable parts" inside of timers. Timers are opaque values that we shouldn't touch; we should only pass them to clearTimeout or clearInterval.