Robert Holden Robert Holden - 6 months ago 114
Javascript Question

JQuery Each not waiting for function inside to finish

I have this inside an ajax function

$.each(data['Result'][0], function(Key, Value) {
InputGen(Value['Type'], Value['Name'], Value['Other'], Value['Value'], function(Html){
Table = Table + "<tr><td>"+Key+"</td><td>" + Html + "</td></tr>";
});
});


and
InputGen
has a callback from another ajax function but when i run this the loop does not seem to be waiting for the ajax to finish. how would i achieve this?

Answer

This is because AJAX is asynchronous. Nothing is going to wait for it to finish. The callback will run in the future at some point when the call is done. By then your $.each (and the code after) is long done.

The solution here is to use promises. That way you can run a callback once all the AJAX calls are done.

You can use jQuery's $.Deferred for this. Without editing the InputGen() function, you can do something like this:

var promises = [];

$.each(data['Result'][0], function(Key, Value) {
    var d = new $.Deferred;

    InputGen(Value['Type'], Value['Name'], Value['Other'], Value['Value'], function(Html){
        d.resolve([Key, Html]);
    });

    promises.push(d.promise());
});

$.when.apply($, promises).done(function(){
    for(var i=0, length=arguments.length; i < length; i++){
        var ele = arguments[i],
            Key = ele[0],
            Html = ele[1];

        Table = Table + "<tr><td>"+Key+"</td><td>" + Html + "</td></tr>";
    }

    // In here is where you can use your updated `Table` variable.
    // You *cannot* use it outside of here, since it was not updated yet
});