I've been working on SPA (single-page application) with different frameworks, such as AngularJS and DurandalJS. Most of the time, each partial or viewModel needs multiple restful APIs/Endpoints to render the full UI. Writing nested ajax calls is ugly, painful to debug and most importantly slow. Here I am going to show you an elegant and efficient way to handle multiple ajax calls with jQuery Deferred.
In the following example, I am making 3 ajax calls in a single function. Here is the ugly, painful, slow way to do it.
function getLocation() { $.get("http://ipinfo.io", function (response1) { if (response1) { $.get("http://ipinfo.io", function (response2) { if (response2) { $.get("http://ipinfo.io", function (response3) { if (response3) { // handle the rest } }, 'jsonp'); } }, 'jsonp'); } }, 'jsonp'); }
I'm sure you've done this before. At least I've done it. Because it works. But it's so slow:
ajaxCall1 -> wait to be done ->
ajaxCall2 -> wait to be done ->
ajaxCall3 -> wait to be done -> go
If we could do this: All three requests in parallel:
wait for all three ajaxCalls to be done -> go
It would be much faster. With jQuery $.deferred object, you can not only make multiple ajax calls efficiently, but also make it chainable. Here you go:
var deferred = $.Deferred(); function getLocation() { var ajaxCall1 = $.get("http://ipinfo.io", {}, null, 'jsonp'); var ajaxCall2 = $.get("http://ipinfo.io", {}, null, 'jsonp'); var ajaxCall3 = $.get("http://ipinfo.io", {}, null, 'jsonp'); $.when(ajaxCall1, ajaxCall2, ajaxCall3) .done(function (response1, response2, response3) { if (response1[0].country === 'US') { deferred.resolve(); } else { deferred.reject(response1[0], response2[0], response3[0]); } }); return deferred.promise(); } getLocation() .then( function () { alert('You are in US'); }, function (response1, response2, response3) { alert('You are in ' + response1.city + ', ' + response2.region + ', ' + response3.country); } );