1

I have a simple function to display a console message with an item name. Something simple like:

for(var i =0; i< array.length; i++)
child(array[i]);

var child = function(itemname){
console.log(itemname);
}

Here length of array is dynamic and so are the values it contains. Now I want to add some animation inside the child function and definitely want it to finish first before it gets called again by the for loop.

I know how to use jQuery Deferred and can call one function after finishing other but here I don't know how to call use it inside a for loop. I'm not sure if that's the right option to use here. So, what I want to do is,

for(var i =0; i< array.length; i++) //for example 3 times
{

child(i) //call child and pass the the value of i
wait till child function completes

}

So, with every increment in i, child function will be called and for loop should wait until child function is completed and then call child function again.... till the condition is met.

I found some solutions with $.when.apply functionality but couldn't figure our how to use it. Any documentation, sample, reference, 'to read' article will help!

EDIT: I guess, I shouldn't have used the example of animation. my bad. Assume that the child function makes an ajax call. Now, I want to call the child function i times and want the loop to wait every time to let the ajax call to complete before calling it again. It is the same function which I want to call more than once. no chaining.

sandiejat
  • 2,552
  • 19
  • 24
  • Doesn't it wait for completion already? I mean as far as I know execution of your code should be linear. As in statements will be executed in order and each statement will wait until the previous is executed. – Zero Oct 22 '14 at 07:29
  • I guess not, since jQuery will make an asynchronous call to the child function and then the for loop won't care to wait till the animation inside the child function completes. Assume that you have an AJAX call inside the child function and you want to call this child function 10 times and want the for loop to wait every time to let the call finish and then call child function again. Am I making sense? – sandiejat Oct 22 '14 at 07:38

2 Answers2

1

You don't need for loop here, it's not really a right tool for chained animations. Instead you can use built in jQuery.Deferred object. Below is an example of how you can use it. As you can see what you would need to do is to make your animation function child return deferred object. After that you can use its then method to decide if you need to call child one more time, until array contains elements.

var array = ['message one', 'and another', 'finally one more'];

// Invoke child until array has elements, no loops are needed here
child(array.shift()).then(function next() {
    if (array.length) {
        child(array.shift()).then(next);
    }
});


// An example of child function.
// Important part here is that this function returns deferred promise
// which is resolved once animation is complete.
function child(i) {
    var $message = $('<div class="message">' + i + '</div>');
    $message.appendTo('body');
    return $.Deferred(function() {
        $message.delay(1000).fadeOut(1000, this.resolve);
    });
}
.message {
    padding: 20px;
    background: #55E755;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

UPD. If you have some AJAX call in child function it's even simpler. You just return something like this $.get(...), it's already a promise, no need to construct new one with $.Deferred.

dfsq
  • 191,768
  • 25
  • 236
  • 258
0

How about doing it recursively?

function child(i){
    if(i<array.length){
        console.log(array[i]);
        child(i+1);
    }
}

var array = ['1','2','3'];

child(0);
roullie
  • 2,830
  • 16
  • 26