简体   繁体   中英

Timing issue with setTimeout

The code below demonstrates the issue I am having.

When the the js executes, the progress bar fills, as expected rapidly until the max has been reached.

However, the span#pbarval container is updated very slowly and completes LONG after the progress bar has finished.

$(document).ready(function () {
    var max= 20000,
        cur=0;
    function updatePBar(){
        cur++;
        jQuery("#pbar").val(cur);
        jQuery("#pbarval").html("" + Math.ceil(cur*100/max) + "%");
        if (cur<=max){
            setTimeout(updatePBar, 10);
        }
    }
    updatePBar();
});

You can see the code executing here: http://jsfiddle.net/EricBrian/fhtp6rpf/

Can somebody explain why this is? How to make it keep up with the progress bar?

Also, I noticed that if I switch tabs, the setTimeout seems to pause. The percentage does not update until I switch back to the tab it is running in.

Thanks! -e

You're using cur for the value of the progress bar, so the progress bar is full when cur === 100 , but you're displaying cur*100/max as the percentage which doesn't reach 100% until cur == 20000 .

You should use the same formula cur*100/max for both, and since you want the quick speed you should also divide your max by 100:

http://jsfiddle.net/Paulpro/fhtp6rpf/2/

$(document).ready(function () {
    var max= 200,
        cur=0;
    function updatePBar(){
        cur++;
        jQuery("#pbar").val(cur*100/max);
        jQuery("#pbarval").html("" + Math.ceil(cur*100/max) + "%");
        if (cur<max){
            setTimeout(updatePBar, 10);
        }
    }
    updatePBar();
});

I also changed the test cur<=max to cur<max since you probably do not mean to increment cur an extra time when it is already at max .

Your progress bar max is 100 but your javascript variable max is 2000.

As such, the progress bar fills much quicker because it reaches it right away.

This particular expression is the one guilty for it:

Math.ceil(cur*100/max)

Looks like below expression is taking too long.

Math.ceil(cur*100/max) 

Simply replace that expression with

cur

and see how it flies.

This is an answer to part of your question. setTimeout is designed to be active when the tab is active. So the behavior regarding the progress bar not being updated when the tab is no active is normal. You can over come this using this method here .

It's just wrong at your cur

$(document).ready(function () {
     var max= 20000,
         cur=0;

     function updatePBar(){
         cur++;
         var value = Math.ceil((cur/max) * 100);
         jQuery("#pbar").val(value);
         console.log(cur)
         jQuery("#pbarval").html("" + value + "%");
         if (cur<=max){
             setTimeout(function(){updatePBar();}, 10);
         }
     }
     updatePBar();
});

You are assigning different value to the value of the progress and to the percentage.

Just reuse the same value:

 var max = 20000, cur = 0; (function updatePBar() { pbarval.innerHTML = (pbar.value = Math.ceil(++cur * 100 / max)) + "%"; if (cur < max) setTimeout(updatePBar, 10); })(); 
 <progress id="pbar" value="0" max="100"></progress> <span id="pbarval"></span> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM