for循环中的进度条

Kim*_*mmi 2 javascript for-loop progress-bar

我需要在javascript中的for循环中使用进度条

for(index=0; index < 1000; index++){

// set progress bar value to  index/1000 * 100 + '%'
Run Code Online (Sandbox Code Playgroud)

}

我注意到我们可以把它放在一个setInterval函数中,但运行for循环会花费更多的时间.

那么有没有办法运行for循环并生成进度条而不需要花费更多时间?

T.J*_*der 8

那么有没有办法运行for循环并生成进度条而不需要花费更多时间?

大多数情况下没有(参见下面的"大多数"为什么),你必须回到浏览器(例如,通过setTimeoutsetInterval),这样它可以更新页面显示,这确实会增加循环运行的时间.现在,通常如果您使用超时0,浏览器将在5到10毫秒之间回拨您.所以称它为10ms.在1000个循环的循环中,您可能每100个循环产生一次(例如,10个进度更新),这只会在总时间上增加100ms左右.

FWIW,看起来像这样(让我们说它是一个你正在循环的数组):

function loop(array, batchSize, callback) {
    var index = 0;

    doWork();

    function doWork() {
        var limit = Math.min(array.length, index + batchSize);
        while (index < limit) {
            // Do something with array[index]
        }
        if (limit < max) {
            setTimeout(doWork, 0);
        }
        else {
            callback(); // Done
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用:

loop(someArray, 100, function() {
    // Done
});
Run Code Online (Sandbox Code Playgroud)

为什么"大多数"不是:在某些浏览器(不是,特别是IE9或更早版本)上,对于某些任务,您可以使用Web工作者.Web worker是一个独立的JavaScript线程,与主JavaScript线程分开,后者在后台运行.这两个线程通过彼此发送消息进行通信.

因此,您可以启动Web工作人员,将工作交给他,并让它发布消息以更新您的进度条.如果您想要走这条路,本文将介绍Web工作者的基础知识.

对于它的价值,它看起来像这样:

主要文件和脚本:

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Progress</title>
<style type="text/css">
body, html {
  height: 100%;
}
body {
    font-family: sans-serif;
}
</style>
</head>
<body>
<div id="progress"><em>(Click to start)</em></div>
<script>
(function() {
  var div = document.getElementById("progress");
  var counter = new Worker("counter.js");

  div.addEventListener("click", run);

  counter.addEventListener("message", function(event) {
    div.innerHTML = "Counter so far: " + event.data.counter;
  });

  function run() {
    div.removeEventListener("click", run);
    counter.postMessage({ max: 10000000 });
  }
})();
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

counter.js web-worker脚本(它们总是单独的文件):

self.addEventListener("message", function(event) {
  var max;
  var counter;

  max = event.data && event.data.max || 100000;
  for (counter = 0; counter < max; ++counter) {
    if (counter % 1000 === 0) {
      self.postMessage({counter: counter});
    }
  }
  self.postMessage({counter: counter});
});
Run Code Online (Sandbox Code Playgroud)