for loop a function with deferred

心已入冬 提交于 2019-12-11 11:18:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!