SetTimeout vs Promises

idineshgarg
4 min readDec 23, 2021

--

Promises vs SetTimeout | JAVASCRIPT

It is a very common asked interview question. I was asked a same question in an interview but could not answer it. I highly recommend to watch this video on Event loops before moving any further.

Event Loops In Javascript

Javascript is a single threaded programming language which means is has only one CALL STACK. To perform any asynchronous task you have to stop the main CALL STACK and wait until the function is popped out of the call stack. For example, if you want to fetch a data from api, you have to wait until the data is fetched and whole DOM will be blocked until the data from the api is fetched. To get rid of such a problem, the concept of event loops was introduced. The web api along with task and job queue adds power to perform asynchronous task without blocking the main thread.

Promises VS SetTimeout

Let us consider an example. Consider a promise and a setTimeout as given below. What will be the output of the following code??

Promise.resolve(1).then(function resolve() {
console.log('Resolved!');
});
setTimeout(function timeout() {
console.log('Timed out!');
}, 0);

Think before moving to the answer. Both are asynchronous which one will be moved to call stack first. Yes you guessed it right. Promise will get resolved first and the output will be.

Resolved!Timed out!

Now consider this other way around.

setTimeout(function timeout() {
console.log('Timed out!');
}, 0);
Promise.resolve(1).then(function resolve() {
console.log('Resolved!');
});

What will be the output now. Bit confused? Thats where the concept of Task queue and job queue comes handy. Give it a shot.

You’ll be amazed to know the output is still the same. Promises are faster than setTimeout.

Resolved!Timed out!

But what is the reason behind? For knowing the logic behind this behaviour, we have to jump a bit more into Event loops and Web API’s.

Job queue vs task queue

Let’s look again at the experiment from the event loop perspective. I’ll make a step by step analysis of the code execution.

1. The call stack executes setTimeout(..., 0) and schedules a timer. timeout() callback is stored in Web APIs:

setTimeout(function timeout() {
console.log('Timed out!');
}, 0);
Promise.resolve(1).then(function resolve() {
console.log('Resolved!');
});

2. The call stack executes Promise.resolve(true).then(resolve) and schedules a promise resolution. resolved() callback is stored in Web APIs:

3. The promise is resolved immediately, as well the timer is timed out immediately. Thus the timer callback timeout() is enqueued to task queue, the promise callback resolve() is enqueued to job queue:

4. Now’s the interesting part: the event loop priorities dequeueing jobs over tasks. The event loop dequeues the promise callback resolve() from the job queue and puts it into the call stack. Then the call stack executes the promise callback resolve():

'Resolved!' is logged to console.

5. Finally, the event loop dequeues the timer callback timeout() from the task queue into the call stack. Then the call stack executes the timer callback timeout():

setTimeout(function timeout() {
console.log('Timed out!');
}, 0);
Promise.resolve(1).then(function resolve() {
console.log('Resolved!');
});

'Resolved!' is logged to console.

The call stack is empty. The script execution has been completed.

Summary

Why an immediately resolved promise is processed faster than an immediate timer?

Because of the event loop priorities dequeuing jobs from the job queue (which stores the fulfilled promises’ callbacks) over the tasks from the task queue (which stores timed out setTimeout() callbacks).

--

--

idineshgarg

With many years of experience in the IT industry, I have developed a strong foundation in a variety of programming languages and software development methods.