Explaining few strange behavior of setTimeout() with code snippet

Previously also we showed you few tricky behavior of JavaScript codes. Today also few more strange things you are going to observe. The following code snippets which describes JavaScript event loop will not only help you to improve your JS knowledge, but also can be useful for you to write logic.

Snippet 1: Guess the output of the following code

function test(){
	setTimeout(function(){
		console.log("setTimeout function is executed");
	},20);

	for(var i=0; i<1000; i++){
		console.log(i);
	}
}
test();
&#91;/code&#93;
Will it print "setTimeout function is executed" right after 20 milliseconds? Than what about the loop console.log()? Is the loop going to be broken? Or the browser will ignore the setTimeout completely? 

<h3>The output is:</h3>
It will complete iterating the loop; will print till 1000 and then it will execute the function inside setTimeout. Far after 20 milliseconds.


<h2>Snippet 2: Guess the following too</h2>

function test(){
	setTimeout(function(){
		alert("setTimeout function is executed");
	},20);

	for(var i=0; i<1000; i++){
		console.log(i);
	}
}
test();
&#91;/code&#93;
This code snippet is very much similar to the previous one. So can we expect a similar output? Well, strange thing is, the answer is NOT.

<h3>The output is:</h3>
It will iterate as much as it can in 20 milliseconds, then execute the alert and then print the rest.

<h2>Snippet 3: This one will be simple to guess</h2>

(function() {
    console.log(1); 
    setTimeout(function(){console.log(2)}, 0); 
    console.log(3);
})();

Hope this one will be easier. So, 123? or 132? Well the output will be 132.

What the heck is going wrong?

Nothing! Nothing is wrong. All of these are expected behavior only. Behind everything, only two reasons are there. First, JavaScript is single threaded; second, the event loop.

What is Single thread?

A thread is a pipeline or path of execution through a program. A single-threaded program, always has a single path or a single queue of execution. While in a multi-threaded program, there can be more than one paths of execution.
That means when using a single-threaded program, only a single task can be performed at a time and the program waits until the running task is finished before starting another one.

A light on JS event loop

Event loop is sort of a task runner. It runs the functions one after one from the call stack. When a running function returns, the event loops initiates the second function. A brief on JavaScript event loop is given in carbonfive.

Describing Snippet 1

Here what the code did is, the moment it completes 20 milliseconds, JS event loop finds the JavaScript interpreter is busy performing other tasks (for loop execution). So it pushed the function inside setTimeout in the waiting queue (JS is single threaded, so there is just a single queue). Once the interpreter finishes executing the looping task, the JS event loops pulls out the waiting function and executes. Thus the "setTimeout function is executed" is printed after finishing printing up to 999.

Why alert() is executed?

In the second snippet if you see, only the console.log("setTimeout function is executed") has been replaced by alert(). So why in this case "setTimeout function is executed" output is prompt in between? Why it didn't executed after finishing the for loop?
Actually here also the setTimeout() is triggered after the loop is finished, it's just the displaying which has different timing. Though JavaScript is single threaded, but the browser has multiple threads. One thread is used to print in console and there is another which is to manipulate DOM. console.log() is a console function whereas alert() is a DOM manipulation. Thus, both goes in different queues as the threads to handle them are different. While one thread was busy doing console.log, the second one has just one job; to show the alert box. So they ran parallely easily. Same will happen in case of .innerHTML() too.

Explaining snippet 3:

After reading the first two explanation, I think it will be easy for you to guess the third. Even though the setTimeout duration is 0 milliseconds, but the execution will be similar. It will be stored to waiting queue and executed later.

About This Author

Hello! I am Paul Shan, a JavaScript Expert, Full Stack and DevOps Engineer cum Consultant based out of Bengaluru, India.

  • anon

    What browser are you testing this in? This is not reproducible.
    Notice that even the alert() call is executed *after* all the console.log(i) calls, there’s nothing that would change between snippet1 and snippet2. The only thing that might be is that your browser is not capable of printing console output and displaying alert popups at the same time.

    • metalshan

      In all browsers it will be same. Probably your comp was fast that’s why executed the console.log() before 50 milliseconds. Make the timeout 10 and then check. I’ve made the timeout 20 in this article now, so that people with fast PC don’t face the issue again

  • leahciMic

    This is not correct at all. The loop finishes in both cases. JavaScript is single threaded like you mentioned, it’s NEVER going to interrupt that loop, not from a timeout, or any other event/callback.

    The behaviour you’re witnessing is that console.log itself is asynchronous. It returns before the data is written onto the console (in order to be non-blocking), and will queue the data to be written later. The alert is then reached, and displays the alert before the console system has finished processing it’s queue.

    • metalshan

      Sorry for the misconception and thanks for notifying. Have modified the paragraph.