I have been reading about jQuery’s deferreds, but I can’t quite grasp how to use them.
I have the following deeply nested code
Repository.Projects.GetStages(function (data) {
var stagesXml = $.parseXML(data.d);
Repository.Projects.GetBenefits(function (data) {
var benefitsXml = $.parseXML(data.d);
Repository.Projects.GetPriorities(function (data) {
var prioritiesXml = $.parseXML(data.d);
Repository.Projects.GetDifficulties(function (data) {
var difficultiesXml = $.parseXML(data.d);
Repository.Projects.GetFactors(function (data) {
var factorsXml = $.parseXML(data.d);
Repository.Projects.GetRatings(function (data) {
var ratingsXml = $.parseXML(data.d);
Repository.Projects.GetProjectRatings(selectedPersonIdEncrypted, passDate, function (data) {
var dataDoc = UTL.Utility.prototype.setDomDocument(data.d);
var xsltDoc = UTL.Utility.prototype.setXslt("Xslt/UserRating/ProjectRatings.xslt");
var html = UTL.Utility.prototype.transform(dataDoc, xsltDoc, [
['stages', stagesXml],
['benefits', benefitsXml],
['priorities', prioritiesXml],
['difficulties', difficultiesXml],
['factors', factorsXml],
['ratings', ratingsXml]
]);
$('#Project', $content).html(html);
});
});
});
});
});
});
});
Each Repository.Projects.* method contains an asynchronous call to get data. The function passed in is the callback, which is passed the resulting data on success. The Repository handles the errors with a generic function, so I don’t need to pass in an error function. I need to ensure each of these has been called, and the data returned, prior to the xslt transformation.
The methods in Repository.Projects.* all look like this
GetStages: function (successCallback) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "DataRepository.asmx/GetStages",
cache: false,
data: JSON.stringify({}),
dataType: "json",
success: successCallback,
error: Repository.FailureCallback
});
}
It seems like I should be able to rewrite this, I just can’t see how.
You want all of your functions under
Repository.Projects.*to return the$.ajaxcall (which itself returns a deferred instance).Then you can use this code:
EDIT:
You could make this cleaner by wrapping the
Repository.Projects.*with their own deferred objects.Keep in mind the cleaner implementation won’t work with the code above. The success function will only receive the contents that it needs to pass to
$.parseXML. So you could change the done function variables to$.parseXML(stageResponse).If the only thing
Repository.Projects.Get*functions do is make$.ajaxrequests, I’d get rid of them entirely.Sexy way: