skip to Main Content

Trying to figure out why the output of the following code is the way it is

console.log("Start");

setInterval(function() {
    console.log("setInterval");
}, 5000);

let date = new Date();
while(new Date() - date <= 10000) {}

console.log("End");

Actual Output

  • Start
  • …. 10 seconds ….
  • End
  • setInterval
  • …. 5 seconds ….
  • setInterval

Since the while block blocks the main thread for 10 seconds, the callback function of setInterval should have been pushed twice in the task queue since it has a timer of 5 seconds. So the output should have been

Expected Output

  • Start
  • …. 10 seconds ….
  • End
  • setInterval
  • setInterval
  • …. 5 seconds ….
  • setInterval

2

Answers


  1. The while is blocking the thread, even if the setInterval is asynchronous and written before.

    That is because javascript is running on a single-thread, so if you start a long code that isn’t asynchronous it will block the thread during the time that runs.

    Login or Signup to reply.
  2. Code executed by setInterval() runs in a separate execution context than the function from which it was called.
    From: https://developer.mozilla.org/en-US/docs/Web/API/setInterval

    This does not means that anything that runs through setInterval() runs in a parallel process… It’s a common mistake that I myself made plenty of times.

    The following line literally clogs your script execution in a way that your setInterval() was left without room to calculate its own timelapse.

    while(new Date() - date <= 10000) {}
    

    After your 10 seconds ends, then your setInterval() is free to calculate its own timelapse again (its clock was not ticking because of the clogging). But as it fires only after 5 seconds, then it still fires after the console.log('End').

    Try this instead:

    console.log('Start');
    
    // Runs the function after each 5 seconds...
    var MyInterval = setInterval
    (
       () => console.log('setInterval'),
       5000
    );
    
    // Stops the interval after 10 seconds...
    setTimeout
    (
       () =>
       {
          console.log('End');
          clearInterval(MyInterval);
       },
       10000
    );

    Or, if you really want to start your interval after 10 seconds you could do:

    console.log('Start waiting 10 seconds.');
    
    // Runs after 10 seconds...
    setTimeout
    (
       () =>
       {
          console.log('End of the 10 seconds wait.');
          
          // Runs after each 5 seconds... It not stops.
          setInterval
          (
             () => console.log('setInterval'),
             5000
          );
       },
       10000
    );
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search