Any better way to combine multiple callbacks?

I need to call an async function (with loop) for multiple values and wait for those results. Right now I'm using the following code:

    var when_done = function(r){ alert("Completed. Sum of lengths is: [" + r + "]"); }; // call when ready

    var datain = ['google','facebook','youtube','twitter']; // the data to be parsed
    var response = {pending:0, fordone:false, data:0}; // control object, "data" holds summed response lengths
        response.cb = function(){ 
            // if there are pending requests, or the loop isn't ready yet do nothing
            if(response.pending||!response.fordone) return; 
            // otherwise alert.

    for(var i=0; i<datain; i++)(function(i){
        response.pending++; // increment pending requests count
        $.ajax({url:'http://www.'+datain[i]+'.com', complete:function(r){
            response.pending--; // decrement pending requests count
            response.cb(); // call the callback

    response.fordone = true; // mark the loop as done
    response.cb(); // call the callback

This isn't all very elegant but it does the job. Is there any better way to do it? Perhaps a wrapper?



Async JS to the rescue (for both client-side and server-side JavaScript)! Your code may look like this (after including async.js):

var datain = ['google','facebook','youtube','twitter'];

var calls = [];

$.each(datain, function(i, el) {
    calls.push( function(callback) {
            url : 'http://www.' + el +'.com',
            error : function(e) {
            success : function(r){
                callback(null, r);

async.parallel(calls, function(err, result) {
   /* This function will be called when all calls finish the job! */
   /* err holds possible errors, while result is an array of all results */

By the way: async has some other really helpful functions.

By the way 2: note the use of $.each.


You can use the jQuery Deferred object for this purpose.

var def = $.when.apply(null, xhrs) with xhrs being an array containing the return values of your $.ajax() requests. Then you can register a callback def.done(function() { ... }); and use the arguments array-like object to access the responses of the various requests. to properly process them, remove your complete callback and add dataType: 'text' and use the following callback for done():

function() {
    var response =, '');
    // do something with response


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.