Tim Jansen Tim Jansen - 1 month ago 6
HTML Question

How to make a function which counts for 3 seconds

I want to make a programm which counts how many computational steps the pc can make in 3 seconds it should work basicly like this:

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


Problem is ONE doesnt matter how I trie it does not stop after 3 seconds and TWO because its in a loop the variable i is not displyed while the process.

How to solve this two things?

EDIT:



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>





How to see it counting?

Answer

If you want to have a blocking function than:

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

FIDDLE #1

But this will block the whole UI and if you want an animation »loop«, than:

  (function loop (end) {

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

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

FIDDLE #2

If you compare the output of both versions, you can see that #1 will

start ...
many times sleeping
end ...

and #2

start...
1000
end
many times the delta

This is want blocking is actually referring to. The while loop will run with as much cycles as it can and blocks the thread, while #2 uses a timer, which will call loop as often as possible, but with a maximum of 60 times per second.

UPDATE

Referring to the comment: »How to see it counting« If you are using method #1, than you wont ever see it, because: The while loop will consume all available CPU cycles and runs until time is up. During that it updates the inner HTML, but since this loop block the UI, the Browser has no chance to actually render the result and you will end up with the result rendered. In other words: You simply cannot update the UI as fast as your CPU.

To see anything you need to use method #2, this way the UI is not blocked, because requestAnimationFrame asks the browser to run the callback as often as possible in between the render cycles of the browser, that is why there is a maximum of 60 Frames per Second, because this is the maximum update rate of the browser. If your callback takes longer than 1000/60ms the frame rate decreases accordingly.

If you want to display how many cycles the browser can run in a Interval, you need a different approach, which could be a Web Worker. With that, you can create a second thread, which wont interfere with the UI. Therein you can count the iterations and within the »UI« thread, you can pull that value from the worker and display it each animation Frame.

Please not that JS is single threaded and while this thread is processing anything, the UI hangs and wont be updated until the window »unresponsive script…« pop up and asks you to stop it.

With the code below you might get a count close to the »real« count of iterations. It counts for a fixed frame length, updates the html and than let the browser do the rendering, while counting the cycles is paused. So that will count less cycles than browser actually can.

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