Ryan Ogle
Ryan Ogle

Reputation: 726

Jquery deferred from callback of ajax calls

I'm trying to write an procedure that does something after 2 objects are returned as a result of the callback of an ajax function.

I know the classic example of using Jquery when():

$.when($.get("http://localhost:3000/url1"), 
$.get("http://localhost:3000/url2").done(//do something));

But in my case, I don't want to trigger the when on the execution of the ajax function, I want the when to trigger from the callback from the execution of the ajax function. Something like:

$.get("http://localhost:3000/url1", function(data){
  function(){
    //do something with the data, and return myobj1;
  }
});

$.get("http://localhost:3000/url2", function(data){
  function(){
    //do something with the data, and return myobj2;
  }
});

$.when(obj1, obj2).done(function(){
  //do something with these 2 objects
});

But of course, that doesn't work. Ideas?

Upvotes: 1

Views: 1555

Answers (2)

eringen
eringen

Reputation: 381

or you can do controls yourself

     $(function(){$('body').addClass('doc-ready')})
     var thingsToLoad = ['blabla.js','blublu.js','weee.js'];

     var launch = function(){

     // do whatever you want to do after loading is complete
     // this will be invoked after dom ready.
     // objectCollection will have everything you loaded.

     // and you can wrap your js files in functions, and execute whenever you want.

     }

     var loadTester = (function() {
        var loadCounter   = 0,
            loadEnds      = thingToLoad.length; // total number of items needs to be loaded
        return function() {
          loadCounter += 1;
          if (loadCounter === loadEnds) {
            if ($('body').hasClass('doc-ready')) {
              launch();
            } else {
              /* if body doesnt have ready class name, attach ready event and launch application */
              $(function() {
                launch();
              });
            }
          }
        }
      }());


$.each(thingsToLoad, function(i) {
    $.ajax({
      url      : thingsToLoad[i],
      mimeType : 'application/javascript',
      dataType : 'script',
      success  : function(data) {
        loadTester();
      }
    });
  });

add your files into thingsToLoad array, at the end it will be iterated over and will be loaded after success, it will init loadTester.

loadTester will check length of your thingsToLoad array, when number of loaded files vs files length matches and dom in ready status, it will launch().

if you're just loading html files, or text files, you can pass those (data in ajax function) into loadTester and accumulate there (within a private var like those loadCounter and loadEnds), and pass accumulated array or object to launch()

Upvotes: 0

Trevor
Trevor

Reputation: 9578

That actually should work. jQuery.when() takes multiple arguments and fires once they all have completed returning each results arguments as an array:

var req1 = $.get("http://localhost:3000/url1");
var req2 = $.get("http://localhost:3000/url2");

$.when(req1, req2).done(function(res1, res2) {
    //do something with these 2 objects
});

If you don't want to handle the requests together you can create your own deferreds and use those:

var deferred1 = $.Deferred(),
    deferred2 = $.Deferred();

$.get("http://localhost:3000/url1", function(data){
    function(){
        //do something with the data, and return myobj1;
        deferred1.resolve(myobj1);
    }
});

$.get("http://localhost:3000/url2", function(data){
    function(){
        //do something with the data, and return myobj2;
        deferred2.resolve(myobj2);
    }
});

$.when(deferred1, deferred2).done(function(){
    //do something with these 2 objects
});

Upvotes: 5

Related Questions