Joaquin
Joaquin

Reputation: 89

why div is not updated until the for loop is finished?

In the following HTML page I expect the div being updated while the for loop is running. However, no div update occurs before the end of the loop?

        <!DOCTYPE html>
        <html>
        <body>
        
        <h1>why div is not updated until the for loop is finished?</h1>
        
        
          <div id="myBar"></div>
        
        
        <br>
        <button onclick="afficheHeure()">Click Me</button> 
        
        <script>
        var p1 =  document.getElementById("myBar");
        function afficheHeure(){
            for(i=0; i< 50000; i++){
                setInterval(function(){
                    let d = new Date();
                    let e = d.getTime();
                    p1.innerHTML = e;
                }, 100);
                console.log("i vaut = " + i);
            }
        }
        
        </script>
        
        </body>
        </html>

Upvotes: 2

Views: 1181

Answers (2)

Garrett Motzner
Garrett Motzner

Reputation: 3260

Javascript Functions are "atomic" in the sense that they are not ever interrupted by "async" functions. setInterval registers a function to run asynchronously. It waits until no other functions are running before it runs.

Because you are registering functions with setInterval, those functions don't run until the interval has passed (and no other JS functions are currently running). However, setInterval itself is "non blocking": it just registers the function and then returns. Which means the function it registered has yet to run.

Let's a take a look at writing our own "setDelayed" function as an example (it won't actually wait for a specific interval, but it will let us register functions to run later):

const queue = []
function setDelayed (delayedFunction) {
  queue.push(delayedFunction)
}

function runDelayed () {
  console.info('running delayed functions')
  while (queue.length) queue.pop().call()
  console.info('done with delayed functions')
}

// now we put or code with the loop


 for(let i=0; i< 5; i++){
   setDelayed(function(){
     let e = new Date().getTime()
     console.log({e,i})
   })
   console.log("registered i value", i)
 }

// and now we manually trigger our delayed functions, like JS would normally do automatically
 runDelayed()

Additionally, if you are making DOM updates (like your example), the browser actually waits for your script to finish before rendering any of those changes. So if you have a loop that takes long enough, the browser actually will "freeze" until your loop is finished. There are APIs specifically to prevent this "freezing".

Upvotes: 2

Parth Patel
Parth Patel

Reputation: 296

var p1 =  document.getElementById("myBar");
var i = 0;
var bigArray = ['Hello','Hi','How Are You?','Welcome','Hello','Hi','How Are You?','Welcome','Hello','Hi','How Are You?','Welcome','Hello','Hi','How Are You?','Welcome'];
var itemsCount = bigArray.length;
function afficheHeure(){
  setInterval(function(){
    if(i < itemsCount){
      p1.innerHTML += bigArray[i]+'<br>';
      i++;
      console.log("i vaut = " + i);
    }
  }, 100);
}
<html>
  <body>
  <h1>why div is not updated until the for loop is finished?</h1>
  <div id="myBar"></div>
  <br>
  <button onclick="afficheHeure()">Click Me</button> 
  </body>
</html>

If you want to speed it up, you can adjust the interval speed.

Upvotes: 0

Related Questions