Why setTimeout Does Not Guarantee Time to Execution
3 min read

Why setTimeout Does Not Guarantee Time to Execution

I want to go deeper into the asynchronicity of Javascript through a setTimeout example and why it is not a guarantee of time to execution.

First Lesson

You probably first learned about the asynchronicity of Javascript with setTimeout. The example could go something like the following:

const logOne = () => console.log(1);
const logTwo = () => console.log(2);
const logThree = () => console.log(3);
logOne();
setTimeout(logTwo, 1000);
logThree();

You learned that the order of the logs is:

  • 1
  • 3
  • 2

I want to go deeper into the asynchronicity of Javascript through this example and the question “Does this setTimeout always execute the function in exactly one second (1000 milliseconds) ?”

Call Stack

JavaScript does one thing at a time: only one function is executed at the same time. The Stack is the part that controls the execution order.

Every call to a function is sent to the Stack and executed. Let’s take a look at what happens in the previous example:

  • logOne is sent to the Stack and executed.
  • setTimeout(...) is sent to the Stack and executed, but the logTwo inside is not run. We’ll see more on this later. But the setTimeout finishes and is removed from the Stack.
  • logThree goes to the stack and is then executed.
  • After one second, logTwo appears in the stack and is executed.

Asynchronicity in Javascript

The Runtime Environment provides Javascript with a set of functionalities for “parallelizing” tasks. setTimeout is one of those functionalities.

When we use these functionalities, the task that we are parallelizing is sent to some kind of background process. Once the background process finishes, it sends the function to a Message Queue. Finally, the functions are forwarded from the Message Queue to the Call Stack to be executed.

In the previous example, when setTimeout is in the Stack, it sets a process in the background. When this process finishes, it sends logTwo to the Message Queue, from which it will be moved to the Stack.

Event Loop

For logTwo to be executed, it needs to be moved to the Stack. Yet, what if the Stack is full of other functions? Who decides to move something from the Queue to the Stack?

The answer is the Event Loop. The Event Loop is a simple program that does something similar to:

while (queue.waitForMessage() && stack.isEmpty()) {
  queue.sendNextMessageToStack()
}

The Event Loop waits for messages and only moves the function to the Stack when it’s empty.

So, what happens if the Stack is not empty and there are messages in the Queue? They stay in the queue until the Stack is empty. Therefore, the functions are not executed immediately.

First Lesson and More

In a nutshell, setTimeout sends logTwo to the background and waits one second, then the background process sends the function to the Queue. But the function is not executed until the Stack is empty. So, logTwo may take longer to run than one second.

We know that the background process sends logTwo to the Queue in one second. Yet, that does not guarantee that it’s immediately forwarded to the Stack and executed.

setTimeout is a guarantee to a minimum time of execution.

I wrote two gists that you can copy and paste into the console to check this.

Further Resources

  • Event Loop explained on MDN.
  • If you find this article slightly interesting, you will love this video of thirty minutes explaining the Event Loop. Web to see the Event Loop in action.

If you like this post, consider sharing it with your friends on twitter or forwarding this email to them 🙈

Don't hesitate to reach out to me if you have any questions or see an error. I highly appreciate it.

And thanks to Michal and Bernat for reviewing this article 🙏

Thanks for reading, don't be a stranger 👋

GIMTEC is the newsletter I wish I had earlier in my software engineering career.

Every other Wednesday, I share an article on a topic that you won't learn at work.

Join more than 5,000 subscribers below.

Thanks for subscribing! A confirmation email has been sent.

Check the SPAM folder if you don't receive it shortly.

Sorry, there was an error 🤫.

Try again and contact me at llorenc[at]gimtec.io if it doesn't work. Thanks!