8

Is it possible to apply a delay to successive iterations of a javascript for-loop using jQuery or underscore? I have a for-loop on my page that I am using to pop up growl notifications when users fulfill certain conditions and if there are multiple conditions I would like to stagger the growl notifications instead of popping up several at the same time. Here is the loop in question:

var badge_arr = response.split("Earned badge:");
//Start at 1 so I'm not getting everything before the first badge
for(i = 1; i < badge_arr.length; i++){
    responseStr += badge_arr[i];
    //Create growl notification
    //badge info echoed back will be of the form 
    //Earned badge: name: description: imgSource
    var badge_info = badge_arr[i].split(':');
    var title = 'NEW BADGE UNLOCKED';
    var text = 'You just unlocked the badge '+badge_info[0]+': '+badge_info[1];
    var img = badge_info[2];
    createGrowl(title, text, img);
} 
3
  • Well dang, I was just about to accept the other answer before it was deleted. Commented Aug 1, 2012 at 18:11
  • @Xander The first element executed immediately for me, and then the rest executed at the same time. I saw that it worked in your JSfiddle correctly though. I have no idea what is up with that. But then again he had to change the parameters of the question, and your solution clearly works, at least for alerts. I'll just assume that I made a mistake implementing it, misplaced braces or something. Commented Aug 1, 2012 at 18:59
  • Possible duplicate of How do I add a delay in a JavaScript loop? Commented Dec 26, 2018 at 13:54

2 Answers 2

33
for(i = 1; i < badge_arr.length; i++){
    (function(i){
        setTimeout(function(){
            responseStr += badge_arr[i];
            //Create growl notification
            //badge info echoed back will be of the form 
            //Earned badge: name: description: imgSource
            var badge_info = badge_arr[i].split(':');
            var title = 'NEW BADGE UNLOCKED';
            var text = 'You just unlocked the badge '+badge_info[0] +
                       ': '+badge_info[1];
            var img = badge_info[2];
            createGrowl(title, text, img);
        }, 1000 * i);
    }(i));
}

Illustration:

for(i = 1; i <= 8; i++){
    (function(i){
        setTimeout(function(){
            document.body.innerHTML += i + "<br/>"
        }, 1000 * i);
    }(i));
} 

Sign up to request clarification or add additional context in comments.

5 Comments

damn was about to point out your error with the lack of * i - you edited it before I could... +1 just for that!
Can you explain why the * i matters?
@tim if you run the example it'll become a-little more evident. the outer loop increments i badge_arr.length times. thus passing into the inner closure 0, 1, 2, etc ... making the setTimeout execute every second (1000 milliseconds).
@Xander, I found this when looking for 'delay in for loop javascript' on google. This function saved me a lot of worries, thanks a lot!
Why can't we have something like sleep?
4

I prefer to use self-invoking function that receives a number of iterations:

(function loop(i) {          
   setTimeout(function () {   

      console.log('hello world'); // your code

      if (--i) loop(i); // iteration counter
   }, 5000) // delay
})(10); // iterations count 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.