0

I know that javascript is single-threaded, meaning javascript runtime (browser or Node, etc) will send time taking tasks to the event loop so that the execution runs smoothly without blocking on the thread it has. But I am a bit confused about how runtime decides what goes to the event loop. (what is some code block has to do to get into the event loop). This may be because of my lack of understanding, but anyway I will elaborate my question with an example.

function first() {
 console.log('first');
}

function second() {
 console.log('second');
}

first()
let i=0;
while(i<1000000000000){
 i++
}
second();

In this senario console prints 'first' then takes huge amount of time (probbly stuck) and prints 'second'. So that while code block is not going in to the event loop.

function first() {
 console.log('first');
}

function second() {
 console.log('second');
}

first()
setTimeout(()=>{},500000);
second();

Here it is not the case, First, it prints 'first' then load setTimeout to the stack, but it takes time, so moves it into the event loop, continue the thread, and prints 'second'. After 500000 ms it setTime will return to the call stack hence the thread.

So I'd like to know why "while block" doesn't go into the event loop but setTimeout does. Is it because, setTimeout is an asynchronous call?. But still how would runtime know it's asynchronous?

melkorCba
  • 458
  • 5
  • 9
  • 1
    `setTimeout(500000);` <-- that ain't right. If you are going to use a timeout, `setTimeout(second, 500000)` Now wait for 8.3 minutes – epascarello Oct 23 '20 at 18:05
  • 1
    https://stackoverflow.com/questions/28650804/does-settimeout-or-setinterval-use-thread-to-fire – epascarello Oct 23 '20 at 18:07
  • 1
    "*runtime will send time taking tasks to the event loop*" - no. There are some tasks that can be "executed" in the background, like waiting for a timer or a network response, and only when these are done the task to go into the event queue is to execute the callback javascript code that was registered for the event. – Bergi Oct 23 '20 at 18:16
  • 1
    Runtime knows you called setTimeout. Whatever you pass as an argument will be executed in an async way. – Wiktor Zychla Oct 23 '20 at 18:16
  • Thanks, guys, it's more clearer now !! – melkorCba Oct 23 '20 at 18:26

1 Answers1

1

Ok, first: the JavaScript engine doesn't know anything about the setTimeout function. At a high level, the JavaScript engine has only a call stack and a heap for memory management. The setTimeout is not part of the JavaScript engine, it is shipped with the Browser's Web APIs. The setTimeout never goes to the call stack, its callback function goes in the appropriate time.

When you call a setTimeout, the browser creates a timer for it and put it in the memory, when the timer ends, the browser grabs its call back function and put it in the event loop tasks queue, not in the JavaScript engine call stack. So, what the event loop actually does is constantly observing the JavaScrip call stack, and, when the call stack is empty it grabs the first task of its tasks queue and put into the call stack.

So, let's say you have the following code:

function first() {
 console.log('first');
}

function second() {
 console.log('second');
}

first()
setTimeout(()=>{},500000);
second();

1st: the function first is added to the JavaScript call stack, it outputs a console.log and then, the first function is removed from the call stack.

2nd: the Browser adds the setTimeout in its web APIs engine, and create a timer for it (500 seconds).

3rd: the function second is added to the JavaScript call stack, it outputs a console.log and then, is removed from the call stack.

4th: When the previous timer ends, the browser puts the setTimeout's callback function (not the setTimeout itself) in the event loop tasks queue, it is ready to run.

5th: The event loop looks at the call stack and waits until the call stack is empty. Ok, it is empty, so the event loop puts the task in the call stack and it is executed.

The same occurs for the case in the setTimeout timer is zero.

setTimeout(()=>{},0);

If the call stack has a lot of tasks, the setTimeout call back function can wait much more time than its timer (second argument)

Note that setTimeout is not a guarantee of time, but of a minimum time.

This is a great lecture about the event loop.

Pablo Darde
  • 5,844
  • 10
  • 37
  • 55
  • Ah, Now I understand. I was so confused about this event loop macahnism. This is a perfect answer. thanks !!. – melkorCba Oct 23 '20 at 19:04
  • 1
    You're welcome bro. I strongly recommend you see the lecture in the link. – Pablo Darde Oct 23 '20 at 19:05
  • *"So, what the event loop actually does is constantly observing the JavaScrip call stack, and, when the call stack is empty it grabs the first task of its tasks queue and put into the call stack."* JS isn't that important, the event-loop has many other tasks to deal with than JS execution. Also there is a prioritization system, so they'll execute the first task of the one task queue they dimmed more important at that time, not just the first one of all. – Kaiido Oct 23 '20 at 23:55
  • You are right @Kaiido, I wanted to keep the concept simple here. But actually, there are tasks, microtasks, and renderer task queues, each one has its own behavior. Also, the event loop deals with the requestAnimationFrame in different ways in Chrome, Safari, Firefox, and Edge. There is a lot of things to be explored in this area. – Pablo Darde Oct 24 '20 at 00:49