Open In App

GFact | Why setTimeout callback doesn’t get called or work?

Every JavaScript Developer must have used setTimeout() method to execute some code after a particular interval of time (let’s say T milliseconds). But more often you might have come across the issue that nothing happens when the setTimeout is invoked, or the setTimeout goes into an infinite loop. In this edition of GFact, we will deep dive into this and understand what happens behind the scenes of setTimeout callback and why doesn’t it get called as expected.

What is setTimeout() callback method?

The setTimeout() method sets a timer that executes a function or specified piece of code once the timer expires.



Consider the following code:




<script>
    startTime = new Date().getTime();
    setTimeout(function gfgCallback() {
        endTime = new Date().getTime();
        alert(`This function is executed after ${Math.floor((endTime - startTime) / 1000)} seconds`);
    }, 3000);
</script>

In the above code, you’ll see that the code inside the callback function gets executed after 3 seconds. As a result, the alert is displayed after 3 seconds timeout, as expected.



What is setTimeout() callback method?

What is setTimeout callback not getting called issue?

Consider the below code.




<script>
    startTime = new Date().getTime();
    setTimeout(function gfgCallback() {
        endTime = new Date().getTime();
        alert(`This function is executed after ${Math.floor((endTime - startTime) / 1000)} seconds`);
    }, 3000);
     
    // The below code is to simulate the execution
    // of millions of lines of code which blocks the
    // Call Stack of a large period of time
    while(new Date().getTime() - startTime < 9000) {
        // Do nothing
    }
</script>

Expected Output:

Actual Output:

Why doesn’t setTimeout() callback not get called after 3 seconds as mentioned in the code?

The setTimeout() method guarantees the execution of a callback function after atleast T milliseconds and after T milliseconds are over, its execution depends on the Call Stack of JavaScript Engine. It might happen that the execution is delayed for a much longer period of time as compared to T milliseconds as it will only start after the Call Stack becomes empty.

As a result, If there is any Execution Context inside the Call Stack, the Callback function will wait for the Call Stack to become empty, before doing the Timeout.

Let us debug this setTimeout Callback not getting called issue step by step

In the above code, you’ll observe that the callback function gfgCallback() gets executed after 9 seconds even when we have set the timer for 3 seconds only.

This happens because the Call Stack was occupied with the Global Execution Context for 9 seconds. The while loop was just to simulate the execution of millions of lines of code. We can see similar behavior while executing a large program which takes a large amount of time to execute.

Now, let’s further explore how JavaScript is executed in the background and what exactly is happening in the above code.

Does setTimeout() guarantee the execution of the code inside the callback function gfgCallback() after exactly T milliseconds?

Unfortunately, the answer is No.

Since JavaScript is a synchronous, single threaded language, it has only one Call Stack and it is always advised that we should never try to block the main thread while executing our JS code.


Article Tags :