Reputation: 20169
I have a function that looks similar to the following:
function refreshData() {
service.getSettings().done(function (settings) {
// DATA 1
service.getData1(settings).done(function (result) {
// do something local with result
// partial resolve 1
});
// DATA 2
var localData = service.getLocalData();
if (localData.length) {
service.getData2(settings, localData).done(function (result) {
// do something local with result
// partial resolve 2
});
} else {
$('#list').empty();
// or partial resolve 2
}
});
}
What I want to do is create a Deferred object for this function so I know when the data refresh is fully done. I know I could chain them together with $.when
but I want the two AJAX calls to run independently and I don't care if one finishes before the other.
I've marked above where I want to each piece to resolve. I'm just not sure how to accomplish this.
My end goal would be a call like this:
refreshData().done(function() {
// hide loader
});
Upvotes: 1
Views: 85
Reputation: 9330
how about something like this,
function refreshData() {
var def1 = $.Deferred();
var def2 = $.Deferred();
service.getSettings().done(function (settings) {
service.getData1(settings).done(function (result) {
def1.resolve(result);
});
var localData = service.getLocalData();
if (localData.length) {
service.getData2(settings, localData).done(function (result) {
def2.resolve(result);
});
} else {
$('#list').empty();
def2.resolve();
}
});
// return aggregated promise
return $.when(def1, def2);
}
refreshData().done(function(r1, r2) {
// hide loader
});
Note: untested
Upvotes: 2
Reputation: 19288
The main things you need to do are :
$.when(partial1, partial2)
.then()
chained to your outer service.getSettings()
You may also want to make failure of the partials observable, as least for debugging.
function refreshData() {
return service.getSettings().then(function (settings) {//note `return` and `.then()`
var partial1, partial2; // declare two promises
// utility function make error observable - avoids repetition below
function handleError(err) {
console.error(err);
});
partial1 = service.getData1(settings).done(function (result) {
//do something local with result
}).fail(handleError);//make failure of partial1 observable
var localData = service.getLocalData();//assume this is synchronous
if (localData.length) {
partial2 = service.getData2(settings, localData).done(function (result) {
//do something local with result
}).fail(handleError);//make failure of partial2 observable
} else {
partial2 = $('#list').empty().promise();//sneaky way to generate a resolved promise
}
return $.when(partial1, partial2);//as we are inside a `.then()`, the promise generated here is effectively returned by refreshData().
});
}
see comments in code
Call as follows :
refreshData().done(function() {
// hide loader
}).fail(function(err) {
// indicate failure
});
Upvotes: 2