0

I was testing closures in Fiddle.

The following piece of code prints all the i values from 0-9 but in random order.

for (var i = 0; i < 10; i++) {
    (function (i) {
        setTimeout(function () {
            alert(i);
        }, 2000);
    })(i);
  }

How do I overcome this problem, that is print the i values in proper order?

The question is not specific to any application/program, but just out of curiosity.

Update:

Only happens in Google Chrome.

Zee
  • 8,300
  • 5
  • 34
  • 58
  • I don't see your issue and the code is properly formatted to print them in the right order! – Lelio Faieta May 21 '15 at 07:27
  • alert show in order for me, are you seeing different behavior? – atmd May 21 '15 at 07:28
  • @atmd. Yes, it prints in a random order for me. Can you try 2-3 times, if still it prints in correct order than I guess the problem is something else. – Zee May 21 '15 at 07:29
  • 2
    it works well in firefox, it prints in a random order in chrome – Luthando Ntsekwa May 21 '15 at 07:32
  • @LuthandoLoot. Just noticed that. Will add that point to the question. – Zee May 21 '15 at 07:35
  • 1
    If you use `console.log(i)` instead of `alert` you will see that it isn't printed in random order, so I think that the problem is from the browser which is displaying the alerts based on the time they were called: most recently will be displayed first and then will continue with the alerts which was not displayed even if they were called earlier – Mihai Matei May 21 '15 at 07:35
  • a similar question was answered here http://stackoverflow.com/a/26540900/4323504 – Luthando Ntsekwa May 21 '15 at 07:39

2 Answers2

1

Indeed, in Chrome it alerts them in random order. I fixed it just by adding i to the time, apparently then the alert queue is ordered properly:

for (var i = 0; i < 10; i++) {
    (function (i) {
        setTimeout(function () {
            alert(i);
        }, 2000+i);
    })(i);
  }

https://jsfiddle.net/hqphbhx3/5/

n-dru
  • 9,174
  • 2
  • 27
  • 41
1

Are you trying to alert the number each 2000 milliseconds? If so, try this:

function printNum(i, max) {
    alert(i);
    if (i == max) return;

    setTimeout(function () {
        printNum(i + 1, max);
    }, 2000);
}

printNum(0, 10);

Otherwise, if you want to alert them after 2000 milliseconds one after the other:

function printNum(i, max) {
    alert(i);
    if (i == max) return;

    printNum(i + 1, max);
}

setTimeout(function () { printNum(0, 10); }, 2000);
Jack
  • 1,579
  • 1
  • 12
  • 18
  • Your second solution is what I wanted. A simple workaround of what I am trying. – Zee May 21 '15 at 07:50