{ Timers. }

Objectives:

By the end of this chapter, you should be able to:

  • Use setTimeout and setInterval for timing future code execution
  • Compare and contrast synchronous vs. asynchronous code
  • Diagram the call stack, heap, and queue, and explain how the event loop works

setTimeout + setInterval

It's quite common to write code that we want to be executed after a specific amount of time. Maybe you want to put a timer in a game, or perform some animation on the page after a fixed amount of time has elapsed. To do this, we use the setTimeout and setInterval functions. Both functions accept a callback function and a time in milliseconds as parameters. The main difference is that the setTimeout function will only run the callback function to be executed once, whereas setInterval will run it an infinite amount of times (until the timer is cleared).

Before digging into the syntax of these functions, let's look at a couple of examples:

setTimeout(function(){
    console.log("Hello!");
},1000);

This will log out Hello! after one second. The second parameter to setTimeout controls how many milliseconds JavaScript should wait before executing the callback function.

What happens if we want to stop the timer? Well, setTimeout and setInterval return a special value called a timer id. If we pass this value in to the clearTimeout or clearInterval method, we can stop our timer! For example, if you copy and paste the following code, you should see that nothing gets logged to the console, because the timer id is cleared before one second has elapsed:

let timerId = setTimeout(function(){
    console.log("Hello!");
},1000);

clearTimeout(timerId);

Let's look at one more example (see below). What is the code doing?

let timerId = setInterval(function(){
    console.log("HI!");
},1000);

setTimeout(function(){
   clearTimeout(timerId);
},3000);

In all of these examples, we see that setTimeout and setInterval take in as their first parameter a function! The function that is passed as a parameter to another function is another example of a callback! To analyze this a little more, we can say that the first parameter to setTimeout and setInterval is a callback function and the second is time in milliseconds.

Asynchronous Code

Another reason why callbacks are such a powerful tool is that they enable us to manage asynchronous code, or code that will be executed at a later point in time.

Before we examine asynchronous code, let's understand a fundamental concept about JavaScript: it is single threaded. What this means is that only one process will happen at a time. This is unlike other languages where you can create your own threads, a process called multi-threading. However, we can write asynchronous code, which may give the impression that multiple things are happening at once, even though this is not the case.

How JS manages asynchronous code

In order to understand how JavaScript manages asynchronous code, we first need to define a few terms:

call stack - where function calls are put (each one is called a "stack frame"). The call stack (sometimes simply referred to as the stack) is a LIFO (last-in-first-out) data structure. You can think of the stack like a stack of cups (last one you put on the stack is the first one that comes off). What that means is that if there is a function on the stack and it is under another function, it can never execute until the function on top has come off the stack (either by returning some value or by executing all the code in the function).

event queue - When an asynchronous event occurs, it gets put into what is called the "event queue" (also known as the queue). It is then moved to the stack when the stack is clear (i.e. when there are no functions on the stack). MDN defines the queue as "a list of messages to be processed. A function is associated with each message. When the stack is empty, a message is taken out of the queue and processed. The processing consists of calling the associated function (and thus creating an initial stack frame). The message processing ends when the stack becomes empty again." The queue is a FIFO data structure (first-in-first-out).

heap - where objects are stored. The heap is an unstructured/unorganized region of memory.

JavaScript internally has something called the "Event Loop", which checks the queue and sees if there are any processes to execute.

Let's examine the event loop in action:

console.log("first");
setTimeout(function(){
    console.log("second");
},0);
console.log("third");

When we run this code, we would expect it to log out "first", "second" and "third", but that's not what happens! It logs "first", "third", "second."

Here's what happens:

  • the first log function goes on the stack, prints out "first," and then it goes off,
  • a message is sent to the queue to log "second" in 0 milliseconds
  • during that time, another log function comes on the stack and prints out "third"
  • now the stack is clear so the callback to the setTimeout goes on the stack and "second" is printed

You can read all about the event loop here.

Exercises

Answer the following questions:

  • What is the difference between setInterval and setTimeout?
  • What is the difference between using setInterval and a loop? Why would you want to choose one over the other?
  • What is the first parameter that setInterval and setTimeout accept?
  • Why is it so important to store the result of setInterval and setTimeout in a variable?
  • What does asynchronous mean in the context of setTimeout and setInterval?

When you're ready, move on to Closures

Continue

Creative Commons License