问题
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.
回答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.
回答2:
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);
来源:https://stackoverflow.com/questions/26502205/for-loop-a-function-with-deferred