How does setInterval and setTimeout work?
Asked Answered
Z

5

39

I was in an awkward situation,

I am working with pure JavaScript for almost 3 years, and I know that JavaScript is single-threaded language, and that you can simulate asynchronous execution using setInterval and setTimeout functions,

but when I thought about how they can work I couldn't clearly understand it. So how these functions affect execution context?

I suppose that in specific time runs only one part of the code and after it switches to another part. If so, then would a lot of setInterval or setTimeout calls affect performance?

Zachery answered 26/2, 2014 at 19:24 Comment(4)
Of course. If you do while(true); then the timeouts and intervals are never going to run.Debatable
Every piece of code you put affects performance, more even so intervals and timeouts because you are making the browser constantly process to decrease a variable. So if you have a lot of them your page will run really slowMottled
They only defer the execution until all other code has executed and the thread is free, they do not create a new thread.Dashiell
Imagine a queue of tasks sorted by execution time. The items at the top of the queue get popped/executed if their execution time < current time. If the thread is blocked before the queue can be checked, then no tasks in the queue will be executed.Marketa
C
53

Javascript is singled-threaded but the browser is not. The browser has at least three threads: Javascript engine thread, UI thread, and timing thread, where the timing of setTimeout and setInterval are done by the timing thread.

When calling setTimeout or setInterval, a timer thread in the browser starts counting down and when time up puts the callback function in javascript thread's execution stack. The callback function is not executed before other functions above it in the stack finishes. So if there are other time-consuming functions being executed when time up, the callback of setTimeout will not finish in time.

Cathartic answered 1/4, 2015 at 13:4 Comment(7)
Although browser has several threads, the setInterval is scheduled on the same that the scriptCumin
"The callback function is not executed before other functions above it in the stack finishes.". I guess this is not true. Please check fiddle jsfiddle.net/er_markar/ycjc77xaPryor
What confuses me is, isn't it unsafe for the timer thread to put the action on the execution queue, as it is not on the same thread as the thread that manages the queue. Won't this cause the queue to be in inconsistant state unless the timer thread can somehow pause the event thread?Matlock
@SunilGarg your fiddle is not correct. It should be setTimeout(alert, 3000) to work as you assume. Doing setTimeout(alert(), 3000) causes to evaluate alert() first, then passing result of alert() to setTimeoutTion
What exactly does the timing thread do? Is it a loop that checks the system time?Sickening
Where does the JavaScript event loop and message queue fit in this scenario? Also, might need some additional explanation on the part where the answer says callback function needs to wait for other functions in the execution stack to finish, because stack by definition is LIFO.Hakon
It is not clear what overhead there is while a settimeout call is in progress for a web page, but nothing else is happening. Does the event loop run or wait for an event? Does the timing thread run in a loop? Is there any cpu loading at all?Krell
L
18

How setTimeout / setInterval work's in JavaScript

Browser has API for Timer function just like API for event ex.

'click'

'scroll'

Assume that you have following code in your application

function listener(){
    ...
}

setTimeout(listener, 300)

function foo(){
    for(var i = 0; i < 10000; i++){
        console.log(i)
    }
}

foo()

![See How Function Execution work's in javascript ][1] [1]: https://i.sstatic.net/j6M6b.png


At this point as per our code we wrote above our call stack will look like

Call Stack -> foo

And let's assume that foo will take 1s to complete it's execution, as we already defined 1 timeout in our code and we are running it before "foo" complete's it's execution i.e at 300ms

What will happen then ?

Does javascript stop executing foo and start executing setTimeout ?

No

As we already know javascript is single threaded so it has to complete execution of foo before moving ahead, but how does browser ensure that after execution of foo the "setTimeout" will execute ?

Here javascript magic comes into picture

When 300ms is expired, the browser's "Timer API" kicks in and put the timeout handler into "Message Queue".

At this point "Message Queue" in above image will look like

Message Queue -> setTimout:listner

And

Call Stack -> foo

And when "Call Stack" becomes empty i.e foo completes it's execution the "Event Loop" as shown in the image will take the message from message queue and push it into stack

The only job of "Event Loop" is when "Call Stack" becomes empty and "Message Queue" has entry in it then dequeue the message form "Message Queue" and push it into "Call Stack"

At this point Message Queue in above image will look like

Message Queue ->

And

Call Stack -> listener

And that's how setTimeout and setInterval works, even though we specify 300 ms in the setTimeout it will execute after "foo" completes it's execution in this case i.e after 1s. And that's why timer specified in setTimeout/setInterval indicates "Minimum Time" delay for execution of function.

Limicolous answered 1/12, 2017 at 10:26 Comment(1)
It is not clear what overhead there is while a settimeout call is in progress for a web page, but nothing else is happening. Does the event loop run or wait for an event? Does the timing thread run in a loop? Is there any cpu loading at all?Krell
M
7

Javascript is single threaded but browser is not.

There is 1 stack where function and statements get executed. there is 1 queue where function are queued to be executed. there are web APIs which can hold the function for particular time, defined in setTimeout and setInterval in event table.

when javascript engine execute js file line by line, if it finds a line as statement or function call it load it on stack and execute but if it is setTimeout or setInterval call, then function handler associated with setTimeout or setInterval is taken out by TIME API (one of web API of browser)and hold it for that time.

Once this time is over, Time Api put that function at end of execution queue.

Now Execution of that function depends on other functions calls which are ahead of in queue.

Note: this function call is called upon window object.

setTimeout(function () {console.log(this)}, 300)

Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}

Mauriciomaurie answered 7/10, 2018 at 7:18 Comment(0)
A
2

JavaScript is a single-threaded scripting language, so it can execute one piece of code at a time (due to its single-threaded nature) each of these blocks of code is “blocking” the progress of other asynchronous events. This means that when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest completing) it gets queued up to be executed later.

setTimeout() when you use setTimeout() it will execute only when its turn comes in a queue, if an earlier event (of setTimeout) blocks due to some reason setTimeout can be delayed than the specified time in setTimeout() function. during the execution of setTimeout callback function, if any event occurs(e.g click event),it gets queued up to be executed later.

setTimeout(function(){
  /* Some long block of code... */
  setTimeout(arguments.callee, 10);
}, 10);

setInterval(function(){
  /* Some long block of code... */
}, 10);

setInterval()

  • Similar to setTimeout but continually calls the function (with a delay every time) until it is canceled.

  • setTimeout code will always have at least a 10ms delay after the
    previous callback execution (it may end up being more, but never less) whereas the setInterval will attempt to execute a callback every 10ms regardless of when the last callback was executed.

  • If a timer is blocked from immediately executing it will be delayed
    until the next possible point of execution (which will be longer than the desired delay). Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified
    delay).

Autotype answered 9/5, 2018 at 6:54 Comment(0)
A
1

Just a note in regards to my experience, If you are going to use setTimeout(), the function will always be delayed (and I mean executed later) or executed after further code which is not 'timeouted'. This may happen even with functions which have delay = 0 and is caused by Event Loop.

See example below:

setTimeout(function() {
    console.log('Second');
}, 0)

console.log('First');
Ashton answered 11/8, 2018 at 13:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.