Cwest Cwest - 5 months ago 14
jQuery Question

Using $.Deferred, promises, and $.ajax to build a dependency response map

I have an array of JS resources I need to request. The order must be maintained, and the responses must be in the order that I request them in. The following requests each one in sequence, but I cannot capture the .done() promise callback on the entire request.

I call the getScripts method from my object:

var depArray = ['file1.js', 'file2.js', 'file3.js'];
getScripts(depArray, global_config.jspath + "/");


This iterates over the array within a $.Deferred() a nested $.when promise...

getScripts : function(arr, path) {
var depMap = [];
$.Deferred(
$.map(arr, function(src) {
$.when(
$.ajax({
url: (path || "") + src + ".js",
success: function (data) {
depMap.push(data);
//return data;
}
}
)
).then(function() {
console.log("request complete...", (path || "") + src + ".js");
return true;
});
})
).done(
function() { alert('completely done!!!!'); }
);
},


The alert('completely done!!!!') is fired immediately, not waiting for the ajax calls to execute and finish. I need to return the depMap array from the method, so I have a map of all the responses, in order, from the call.

The response would be:

['contents from file1.js', 'contents from file2.js', 'contents from file3.js']


But I never have a depMap to hand off at the end. Promises are still a bit baffling to me. Any help is appreciated...

Answer

Ok, some cleanup is needed. First of all, remove $.Deferred - it's not needed since you already have $.when promise. Then you need to construct array of promises and pass it into $.when.

Finally, it can look like this:

getScripts: function(arr, path) {
    // map each promise to its resource and aggregate
    return $.when.apply(null, arr.map(function(src) {
        return $.ajax({url: (path || "") + src + ".js"});
    })).then(function(){
        return [].map.call(arguments, function(x){ return x[0]; }) // just the data
    });
}

Demo: http://plnkr.co/edit/DvBj9PcaTQzskCRIUAHZ?p=preview

Comments