Execute one AJAX request after another AJAX request finished

What you’re experiencing (AJAX works locally, but not on the server) there is a delay problem. Locally everything works that fast, that you can’t see your problem. In short, this is your problem:

AJAX callback (A) executes > AJAX Callback (B) doesn’t know that it has to wait for (A) > You can’t see the problem in your local install as (A) is finished too fast.

So you need to find a way how to tell your Callback (B) that it has to wait for (A). Here’s how:

Register Scripts and move data from PHP to JS

Register and enqueue and localize your data the right way: Wrap it in a function or method and hook it to wp_enqueue_scripts (public/themes), login_enqueue_scripts (password/login/register) or admin_enqueue_scripts. The use wp_localize_script() to move data from PHP to JS and make it accessible there.

add_action( 'admin_enqueue_scripts', 'wpse118772jsObject' );
function wpse118772jsObject()
{
    $scriptHandle="custom-script-name";
    // Should be divided into separate functions or methods
    wp_register_script(
        $scriptHandle,
        plugins_url( __FILE__, 'your/path' ),
        array( 'jquery' ),
        plugin_dir_path( __FILE__ ).'your/path' ),
        true
    );

    wp_enqueue_script( $scriptHandle );

    wp_localize_script(
        $scriptHandle,
        'pluginObject',
        array(
                'ajaxURl' => admin_url( 'admin_ajax.php' ),
                'custom'  => array(
                        // custom data in here
                ),
        ),
    );
}

How to use jQuery AJAX the proper way.

There’re several functions you can use: The default $.ajax({}); function or their shortcuts $.post();, $.getJSON();, etc.

So you can simply use something like the following – using the success/fail object methods.

( function( $, plugin ) {
    "use strict";

    $.ajax( {
        url : plugin.ajaxURl,
        data : {
            // other data
        },
        // We assume you're responding with a proper wp_send_json_success/error() in the PHP Cb.
        dataType : "json",

        // Request transformation possible in here.
        beforeSend : function( xhr ) {
            // Example:
            // xhr.overrideMimeType( 'application/json' );
        },

        // The actual handlers
        success : function( data, textStatus, jqXHR ) {
            // Handle data transformation or DOM manipulation in here.
        },
        error : function( jqXHR, textStatus, errorThrown ) {
            // silent: Log the error
            console.info( errorThrown );
            // loud: Throw Exception
            throw errorThrown;
        }
    } );
} )( jQuery, pluginObject || {} );

If you want to go more in depth and do things really the right way, you’ll have to use method chaining. (There’s still room for improvement left).

( function( $, plugin ) {
    "use strict";

    $.ajax( {
        url : plugin.ajaxURl,
        data : {
            // other data
        },
    } )
        .done( function( data ) {
            // Handles successful responses only
        } )
        .fail( function( reason ) {
            // Handles errors only
            console.debug( reason );
        } )
        .always( function( data, textStatus, response ) {
            // If you want to manually separate stuff
            // response becomes errorThrown/reason OR jqXHR in case of success
        } )
        .then( function( data, textStatus, response ) {
            // In case your working with a deferred.promise, use this method
            // Again, you'll have to manually separates success/error
        } );
} )( jQuery, pluginObject || {} );

Note: For better examples of the wrapper around the callback, take a look at commonjs or AMD and their difference.

Waiting for other AJAX responses

The interesting – and most powerful part of the whole jQuery (and other libararies) AJAX handling – question is how to wait until A is finished to then start B and its processing. The answer is “deferred” loading and “promises”.

I’ll add a quick example. You should maybe think about building and object and separating stuff by appending it via this. to the object, but for an example the following should be enough:

Example (A) This basically like I do it. You’ll have to fill the bits your own.

( function( $, plugin ) {
    "use strict";

    $.when(
        $.ajax( {
            url :  pluginURl,
            data : { /* ... */ }
        } )
           .done( function( data ) {
                // 2nd call finished
           } )
           .fail( function( reason ) {
               console.info( reason );
           } )
        )
        // Again, you could leverage .done() as well. See jQuery docs.
        .then( 
            // Success
            function( response ) {
                // Has been successful
                // In case of more then one request, both have to be successful
            },
            // Fail
            function( resons ) {
                // Has thrown an error
                // in case of multiple errors, it throws the first one
            },
        );
} )( jQuery, pluginObject || {} );

Example (B) I never tried it like this, but it should work as well. Easier to read, but I like $.when() resolved promises more.

( function( $, plugin ) {
    "use strict";

    $.ajax( {
        url : plugin.ajaxURl,
        data : {
            // other data
        }
    } )
        .done( function( data ) {
            // Handles successful responses only
        } )
        .fail( function( reason ) {
            console.info( reason );
        } )
        // Promise finished:
        .then( function( data ) {
            $.ajax( {
                url :  pluginURl,
                data : { /* ... */ }
            } )
                .done( function( data ) {
                    // 2nd call finished
                } )
                .fail( function( reason ) {
                    console.info( reason );
                } );
        } );
} )( jQuery, pluginObject || {} );

If you want to get even more in depth, read the Docs about deferred and then.

async/ await

EDIT As this answer receives quite some attention over the years and already is 8 years old, please take a look at the following snippet.

Keep in mind, that async/await still deals with Promises. It’s just synthetic sugar. Also keep in mind what this refers to, when using short hand functions like seen in handlerB().

That will even work with jQuery.

( function( $, plugin ) {
    const handlerA = async function( plugin ) {
        try {
            let res = await $.ajax( {
                url : plugin.ajaxURl,
                data : { /* some data */ }
            } )
                .done( function( data ) {
                    // Handles successful responses only
                } )
                .fail( function( reason ) {
                    console.error( reason );
                } )
            return res;
        } catch ( err ) {
            console.error( err )
        }
    }
    const handlerB = async data => { /* yet another AJAX request */ }

    // Execute
    // …wait…
    let $resultA = await handlerA( plugin )
    // Now exec B
    let $resultB = await handlerB( $resultA )

    // Do something with $resultB

} )( jQuery, pluginObject || {} );

Leave a Comment