【问题标题】:Progressbar does not update while FOR running JSFOR运行JS时进度条不更新
【发布时间】:2019-05-18 01:34:47
【问题描述】:

我正在创建一个程序,其中 JavaScript 正在处理大量数据,所以我想在进度条上显示进度。

问题来了:在for循环运行的时候,进度条没有更新,然后马上就满了。

document.getElementById("start").addEventListener("click",function(){
    max=1000000
    document.getElementById("pb").max=max
    for(i=0;i<max;i++){
        document.getElementById("pb").value=i+1
    }
    console.log("Finished")
})
<progress id="pb" value="0" max="0"></progress>
<input type="button" id="start" value="Start"/>

我该如何解决这个问题?

如果没有它们可能的话,我不想使用任何 JS 库。

感谢您的帮助!

【问题讨论】:

标签: javascript for-loop dom


【解决方案1】:

你可以使用requestAnimationFrame:

document.getElementById("start").addEventListener("click",function(){
    var max=100;
    var p=0;
    document.getElementById("pb").max=max;
    var update = function () {
      document.getElementById("pb").value=p; 
      p++;
      if (p <= max) requestAnimationFrame(update);
      else console.log("Finished");
    };
    update();
})
<progress id="pb" value="0" max="0"></progress>
<input type="button" id="start" value="Start"/>

或者只是使用setTimeout并增加计时器:

document.getElementById("start").addEventListener("click",function(){
    max=100;
    document.getElementById("pb").max=max;
    for(i=0;i<max;i++){
        setTimeout(function () {
          document.getElementById("pb").value=this;
          if (this == max) console.log("Finished")
        }.bind(i+1), i*16);
    }
})
<progress id="pb" value="0" max="0"></progress>
<input type="button" id="start" value="Start"/>

【讨论】:

    【解决方案2】:

    这是async / await 的一种方法,.. 所以你可以保留你的 for 循环。

    还注意到我已将最大值减少到 1000,因为等待 4 个半小时可能会过大。 :)

    function sleep(ms) { return new Promise((r) => 
      setTimeout(r, ms)); }
      
    async function run() {
      let max=1000;
      document.getElementById("pb").max=max;
      for(let i=0;i<max;i++){
        document.getElementById("pb").value=i+1
        await sleep(0);
      }
      console.log("Finished")
    }
    
    document.getElementById("start").
      addEventListener("click", run);
    <progress id="pb" value="0" max="0"></progress>
    <input type="button" id="start" value="Start"/>

    【讨论】:

    • 注意setTimeout有4ms的限制stackoverflow.com/questions/9647215/…
    • @rafaelcastrocouto 是的,但是对于进度条来说应该足够了。
    • 是的,您可以将其设置为 16 毫秒,您的代码仍将处于 60 fps 限制内。
    猜你喜欢
    • 2021-05-29
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    相关资源
    最近更新 更多