为什么在for循环完成之前不更新div?

时间:2020-09-21 16:19:09

标签: html loops display

在下面的HTML页面中,我期望在for循环运行时div正在更新。但是,循环结束前是否没有div更新?

        <!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>

2 个答案:

答案 0 :(得分:1)

JavaScript函数是“原子的”,就意味着它们永远不会被“异步”函数打断。 setInterval注册了一个函数以异步运行。它一直等到没有其他功能在运行。

因为您正在向setInterval注册函数,所以直到间隔过去(并且当前没有其他JS函数正在运行)之后,这些函数才会运行。但是,setInterval本身是“非阻塞”的:它只是注册函数然后返回。这意味着它注册的功能尚未运行。

让我们以编写我们自己的“ setDelayed”函数为例进行观察(它实际上不会等待特定的时间间隔,但是它将让我们注册函数以便以后运行):

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

此外,如果您要进行DOM更新(例如您的示例),则浏览器实际上会等待脚本完成,然后再呈现任何这些更改。因此,如果您的循环花费了足够长的时间,则浏览器实际上将“冻结”,直到循环结束为止。有API个专门用于防止这种“冻结”的。

答案 1 :(得分:1)

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>

如果要加快速度,可以调整间隔速度。