I think the problem is that $.Deferred and the likes are designed for handling async and concurrent procedures, so you will always have to trick them somehow if you want to have them act the way you are describing it.
If you want/need to process your calls one after the other (using AJAX) I'd suggest putting them into an Array and using a simple recursive function to loop through that array until all calls are done or one of them failed.
This would basically work like:
var requests = [
{
url : '/serviceA'
data : myParams4ServiceA
},
...
{
url : '/serviceZ'
data : myParams4ServiceZ
}
];
Now that you have an Array of AJAX requests you can build a recursive function that will work through them one by one:
function work(){
$.ajax(requests[0]).done(function(data){
//handle data here
requests.shift(); //request is done and can be removed from the Array, request[0] will now be the next request in the queue
if (requests.length){
work(); //function calls itself again if there's still need for it
} else {
// we are done!
}
}).fail(function(e){
//call failed -> handle error
});
}
work();
See this fiddle for an example of a successful chain, and this one for a chain that fails.
Another possibility would be setting the AJAX calls to async : false (note that this is deprecated in jQuery 1.8+ : "As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the complete/success/error callbacks." which is pointing us back up again), and use a simple $.when().then().fail() chain that you apply to your array of requests like:
$.when.apply($, requests).then(function(){
$.each(arguments, function(){
//do stuff with your data
});
}).fail(function(){
//handle the error
});
As your calls are blocking now this will also process them in a row. See a fiddle for that as well.
async: false(undoing the A in AJAX)? Or did I get your question wrong?