user531065
user531065

Reputation: 773

Organizing Javascript with callbacks

I am trying to figure out the best way to organize a bunch of AJAX methods on my site. The problem is that I want to run a bunch of callbacks after each one is received. Here's an example (assume each method runs asynchronously):

Log_in_user
    if response received and call was successful
        get_user's_data
            if response received and call was successful
                alert user

Hopefully by now the problem is clear. Because each method runs asynchronously, the code will not run in order. If instead, I want to pass the next function to run as a callback to run after the function that proceeds it, I will have to pass an increasingly large number of callbacks to the first function depending on how many things I want to happen after each asynchronous method returns. For example, in this case, I will have to pass two callbacks to the Log_in_user function Log_in_user(get_user's_data,alert_user). The more callbacks I have running after each other, the more callbacks I will have to pass to the original Log_in_user function.

Is there a more modular and better organized way to do this?

Upvotes: 2

Views: 510

Answers (3)

sic1
sic1

Reputation: 486

I have been adding callbacks to my functions like this...

function doThis( cb ) {
  // do stuff here
  if ( typeof cb === 'function' ) cb();
}

function thenThis() {
  // callback functionality
}

doThis( thenThis );

EDIT:

Sorry, I really should have read through what you needed to do a bit more...

When is a great option for handing pure ajax calls, but, if extra functionality needs to happen in the callbacks, i have found a different patter that helps me organize my code...

// Log_in_user
//     if response received and call was successful
//         get_user's_data
//             if response received and call was successful
//                 alert user

var ajax = {
        logIn : function( cb ) {
            $.ajax({
                // params
            }).success( parseCB ).error( this.errorCB );
            function parseCB( doc ) {
                // logic
                if ( typeof cb === 'function' ) cb();
            }
        },
        userData : function( cb ) {
            $.ajax({
                // params
            }).success( parseCB ).error( this.errorCB );
            function parseCB( doc ) {
                // logic
                if ( typeof cb === 'function' ) cb();
            }
        },
        errorCB : function(){
            // logic
        }
    },
    my = {
        init : function() {
            ajax.logIn( this.done.logIn );
            if ( typeof cb === 'function' ) cb();
        },
        done : {
            logIn : function() {
                ajax.userData( this.done.userData );
            },
            userData : function() {
                // Do stuff with user data, then run my.done.page (the final callback)
                alert( 'user data recieved' );
            },
            page : function() {
                // set up clicks, or whatever else you need
                alert( 'everything is done' );
            }
        }
    };

$( function() {
    my.init( my.done.page );
});

This may seem like a bit much, but my thoughts with this pattern is to keep all my callback and actual function calls within the document ready, and within the my variable. jQuery is my framework of choice, so i put it out there as i would...i'm open to thought here, thanks.

Upvotes: 0

Guilherme Serrano
Guilherme Serrano

Reputation: 136

jQuery 1.5 do that for you, you can use .when()

Example:

function doAjax(){
    return $.get('/echo/html/');
}

function doMoreAjax(){
    return $.get('/echo/html/');
}

$.when( doAjax(), doMoreAjax() )
    .then(function(){
        console.log( 'I fire once BOTH ajax requests have completed!' );
    })
    .fail(function(){
        console.log( 'I fire if one or more requests failed.' );
    });

From jsfiddle

Upvotes: 6

Luke
Luke

Reputation: 8407

why you don´t orgenize this on the server? Do on client side just one call

LoginUserAndGetData

return

{hasErrors: false, userLoggedIn: true, userName : "User", data : {}}

{hasErrors: true, errorMessage: "SomeText", errorCode : "Something you can work with"}

Upvotes: 0

Related Questions