Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

While loop only returning final result

Tags:

javascript

while (counterInc < counter) {
  window.setTimeout(function () {
    $('#results').text(counterInc);
    }, 3000);
  counterInc++;
}

This code should increment the tag with ID results every 3000 milliseconds instead the while loop is running and returning the final result. For example instead of changing the text to 1, 2, 3, 4, 5,..n, it is changing the text to n. How would one have the loop update the text field every 1000 milliseconds with each increment instead of only the final result?

like image 349
Verdi Erel Ergün Avatar asked Aug 21 '12 20:08

Verdi Erel Ergün


People also ask

Why is while loop not terminating?

In other words, a while loop won't stop running as soon as the condition is false. Rather, it stops running once it gets to the point where it reevaluates the condition and finds that it's false. This is why it doesn't matter whether you're using && or || here.

Why does javascript loop only use the last value?

Variable i Always Has The Last IndexBy the time the for loop reaches the last iteration, the i variable will end up holding the last index value. That's why the output will always be the last index, in my case, 5.

How do you return a while loop?

The return statement is useful because it saves time and makes the program run faster by returning the output of method without executing unnecessary code and loops. It is good practice to always have a return statement after the for/while loop in case the return statement inside the for/while loop is never executed.

Do while loops only run once?

There are two variations of the while loop – while and do-While. The difference between the two is that do-while runs at least once. A while loop might not even execute once if the condition is not met. However, do-while will run once, then check the condition for subsequent loops.


3 Answers

Try this

var counterInc = 0;
var counterMax = 10;

var timeoutId = window.setInterval(function() {
    $('#results').text(counterInc++);
    if (counterInc >= counterMax) {
        window.clearInterval(timeoutId);
    }
}, 500);​

http://jsfiddle.net/GufCs/4/

What was happening was you timeout updated the cell every three seconds, however, your loop can run through a ridiculous amount of numbers in 3 seconds, so it's long since complete by the time the function in setTimeout had run.

This will trigger the function every 500ms (change to 3000ms for your purposes) and only then will it increment the counterInc. Add it clears the Interval when it reaches counterMax.

like image 130
CaffGeek Avatar answered Oct 16 '22 10:10

CaffGeek


The problem is that setTimeout() acts as an "independent thread". You set it and it executes once after the specified amount of time. In the mean time the "main thread" keeps running: so your counter will get increased in the meantime.

like image 43
Razvan Avatar answered Oct 16 '22 11:10

Razvan


To understand the problem you need to understand what a closure is. Here you want each time to pass a certain value not the one computed at the end of the loop scope.

So compute the value at the moment you declare the setTimout rather than when it is call you can do as follow: http://jsfiddle.net/lechevalierd3on/jhYm3/

var counter = 10;
var counterInc= 0;

while (counterInc < counter) {
  window.setTimeout(function () {
      var inc = counterInc;
      return function(){
          $('#results').text(inc);
      }
  }(counterInc), 1000 * counterInc);   

  counterInc++;
}​
like image 44
3on Avatar answered Oct 16 '22 10:10

3on