0

I have some javascript code that is being executed before it is supposed to be and I do not know why. Basically, I have a for loop that is supposed to be executed 50,000 times. However, this takes a while so I want to have a progress bar that updates as the for loop is being executed. So, I have an if statement that says if u is at 500, the value of o is set to 0 and the progress bar is updated 1%, and if the progress bar is at 100%, to execute some other code. However, that other code is being executed way before u reaches 100 and I have no idea why.

function thisFunction(){
    var o=0;
    var u=0;
    for(i=1;i<=50000;i++){

        if(o===500){
            o=0;
            u +=1;
            $("#myProgressBar .progress .progress-bar").css('width',u+'%');
            $("#myProgressBar .progress .progress-bar").html(u+'%');

            if(u>99){
                $("#myProgressBar").addClass("hidden");
                /*Other code*/
            }
            else{   
            }
        }
        else{
        }

        /*code that needs to be executed 50,000 times*/
        o +=1;
    }
Siguza
  • 15,723
  • 6
  • 44
  • 66

1 Answers1

3

It's probably because JavaScript, being single-threaded, cannot allow the browser to render the updated progress bar while the for loop is still running.

Generally progress bar updates should be done with requestAnimationFrame or even by using a Web Worker or just generally any kind of asynchronous callback that allows the browser to keep doing stuff while the processing is going on.

Niet the Dark Absol
  • 301,028
  • 70
  • 427
  • 540
  • This seems like the right answer. You may be able to force a browser re-paint by setting a particular CSS property. There are numerous articles on the web for how to do so. Or, you can reference this S.O. question/answer: http://stackoverflow.com/q/8840580/13264 Basically, toggle element.style.display to 'none' and back to 'block' (or whatever is appropriate) while capturing the element.offsetHeight. – Brian Dec 09 '14 at 04:16
  • I appreciate your answer and will keep that in mind, but it is not like the code is being executed after the fact, /* Other code */ is being executed before the for loop even starts (I put a console.log(); statement in the beginning of the for loop and the page was updated before the log showed in my console) – user158679 Dec 09 '14 at 04:17
  • Ah, I see. Sorry for the mis-interpretation. Out of curiosity, try throwing an alert() in, instead of console.log(). I'm fairly certain alert() immediately blocks, but console.log() may be a background web-worker task. Then you should definitely be able to see the state of your function when /* other code */ is called. – Brian Dec 09 '14 at 04:24
  • I dropped your function into a plunker and wasn't able to re-create what you seem to be running into: http://embed.plnkr.co/MoLSFv/preview It does look like your loop counters may be a bit off - for me, u never reaches 100 – Brian Dec 09 '14 at 04:55
  • So I used an alert instead and the alert was shown before the code that needs to be executed 50,000 times was executed. I changed the 2nd if statement to 499 and that solved the u not reaching 100 problem. I am so confused at why this isn't working – user158679 Dec 09 '14 at 20:49