Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using $.Deferred() with nested ajax calls in a loop

I've spent far too many hours searching for similar questions and trying solutions, so I hope someone has a solution.

Basically, I would like to be notified when a function a() has completed. The problem is that the function contains an ajax call and a loop that calls b(), which again contains an ajax call.

UPDATED WITH FIDDLE: http://jsfiddle.net/hsyj7/1/

Like so:

// called by main() function a() {   return $.ajax("http://url1").pipe(function(data){     for (var i = 0; i < 2; i++) {       console.log('a called');       b();     }   }); }  // called by a() function b() {   for (var i = 0; i < 2; i++) {     $.ajax("http://url2", function(data){       // do something       console.log('b called');     }   } }  function main(){   $.when(a()).done(function(){     console.log('all completed');   }); } 

What I would like to see then is, possibly with both calls to a() at the top:

a called b called b called a called b called b called all completed 

Instead I get

a called all completed b called b called 

Or some variant thereof.

I am aware that the above code is missing defer functionality in both the loop and in b(). In some of the variants I have tried, the done() handler in main() is never called.

Any one know how to do this?

like image 619
jokkedk Avatar asked Dec 19 '12 11:12

jokkedk


1 Answers

Yeah, using Deferred is the way to do that:

function a() {     var def = $.Deferred();      $.ajax("http://url1").done(function(data){         var requests = [];          for (var i = 0; i < 2; i++) {              requests.push(b());         }          $.when.apply($, requests).then(function() { def.resolve(); });     });      return def.promise(); }  // called by a() function b() {     var def = $.Deferred(),         requests = [];      for (var i = 0; i < 2; i++) {         requests.push($.ajax("http://url2").done(function(data){             // do something             console.log('b called');         });     }      $.when.apply($, requests).then(function() { def.resolve(); });      return def.promise(); }  function main(){     $.when(a()).done(function(){         console.log('all completed');     }); } 

//EDIT: Replaced .pipe with .done.

like image 112
freakish Avatar answered Oct 06 '22 22:10

freakish