如何制作一个重复3秒的功能

时间:2016-10-19 10:25:36

标签: javascript html while-loop

我想制作一个程序,它可以计算出电脑在3秒钟内可以完成的计算步数,它应该像这样基本工作:

var i = 0;
function count(){
  while(the3seconds are not over)
  {
    i++;
    div.innerHTML = i;
  }
}

问题是一个并不重要我如何在3秒后停止它并且两个因为它在一个循环中变量i在过程中没有显示。

如何解决这两件事?

编辑:

var rechenschritte = 0;
var div = document.getElementById("rechenschritte");
function count(duration) {
    var end = new Date().getTime() + duration;
    
    while(new Date().getTime() < end) {
      rechenschritte++;
    }
    div.innerHTML = rechenschritte;
    rechenschritte = 0;
}
<!doctype html>
<html lang="de">
<head>
      <meta charset="UTF-8">
</head>
<body>

<input type="button" onclick="count(500)" value="Start"/>
<div id="rechenschritte"></div>

</body>
</html>

如何看待它?

1 个答案:

答案 0 :(得分:5)

如果您想要阻止功能而不是:

var end = new Date().getTime() + 3000;
while(new Date().getTime() < end) {}

FIDDLE #1

但这将阻止整个UI,如果你想要一个动画»循环«,而不是:

  (function loop (end) {

      //do stuff
      if (new Date().getTime() < end) {
          window.requestAnimationFrame(function(){
              loop(end);
          });
      }

  })(new Date().getTime() + 3000);

FIDDLE #2

如果比较两个版本的输出,可以看到#1将

start ...
many times sleeping
end ...

和#2

start...
1000
end
many times the delta

这是希望阻塞实际上是指。 while循环将以尽可能多的周期运行并阻塞线程,而#2使用计时器,它将尽可能频繁地调用loop,但最多每秒60次。

<强>更新

参考评论:»如何看待它计算«如果你使用方法#1,那么你将看不到它,因为:while循环将消耗所有可用的CPU周期并运行直到时间结束。在此过程中它会更新内部HTML,但由于此循环会阻止UI,因此浏览器无法实际呈现结果,您最终会得到呈现的结果。换句话说:您根本无法像CPU一样快地更新UI。

要查看您需要使用方法#2的任何内容,这样就不会阻止UI,因为requestAnimationFrame要求浏览器在浏览器的渲染周期之间尽可能多地运行回调,即为什么每秒最多有60帧,因为这是浏览器的最大更新速率。如果您的回调时间超过1000 / 60ms,则帧速率会相应降低。

如果要显示浏览器在Interval中可以运行的周期数,则需要采用不同的方法,可以是Web Worker。有了它,您可以创建第二个线程,它不会干扰UI。在其中你可以计算迭代次数,在»UI«线程中,你可以从worker中提取该值并在每个动画帧中显示它。

请注意,JS是单线程的,当这个线程处理任何东西时,UI会挂起并且不会更新,直到窗口“无响应的脚本...”弹出并要求你停止它。

使用下面的代码,您可能会得到接近“实际”迭代次数的计数。它计算固定的帧长度,更新html,然后让浏览器进行渲染,同时暂停计算周期。因此,这将比浏览器实际可以计算更少的周期。

function displayCount(duration){
    var end = new Date().getTime() + duration,
        cycles = 0,
        frame = 1000/30; //30fps

    (function loop(){
        var now = new Date().getTime(),
            countend = now + frame;

        while(new Date().getTime() < countend) {
           cycles++;
        }

        //UPDATE HTML here

        if(now < end) {
            window.requestAnimationFrame(loop);
        }

    })();
}

FIDDLE #3

相关问题