How does setInterval and setTimeout work?

后端 未结 5 968
一向
一向 2020-11-30 00:57

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

相关标签:
5条回答
  • 2020-11-30 01:06

    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

    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 insure that after execution of foo the "setTimeout" will execute ?

    Here javascript magic comes into picture

    When 300ms is expired the browser "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.

    0 讨论(0)
  • 2020-11-30 01:08

    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.

    0 讨论(0)
  • 2020-11-30 01:22

    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');
    
    0 讨论(0)
  • 2020-11-30 01:25

    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).

    0 讨论(0)
  • 2020-11-30 01:26

    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, …}

    0 讨论(0)
提交回复
热议问题