Ejecute una solicitud AJAX después de que finalice otra solicitud AJAX

Pregunta:

Un archivo JS está haciendo una llamada ajax. Dentro del éxito de esta llamada ajax, se realiza otra llamada AJAX. La segunda llamada comprueba si el correo electrónico ya se ha registrado. Si ha sido así, la segunda llamada AJAX no recibe datos devueltos como se muestra en la consola de Firebug y Chrome en el caso. Pero el mismo código funciona bien en localhost mientras que el problema mencionado ocurre ÚNICAMENTE en el servidor en línea.

La página alojada está en http://twmobilefitness.com/signup/ . El problema ocurre cuando hace clic en el enlace 'Registrarse ahora' al final. Debe registrarse dos veces con la misma dirección de correo electrónico si desea que suceda el problema.

JS:

$.ajax( {
    url : base_url+"/wp-admin/admin-ajax.php",
    type : 'GET',
    cache : false,
    data : 'action=check_user_name&'
           + Math.floor( ( Math.random() * 100 ) +1 )
           + '&user_name='+user_name,
    success : function( result ) {
        if ( parseInt( result ) == 0 ) {
            $( ".result" ).html( '<span class="error">User name not available </span>' );
        } else if ( parseInt( result ) == 1 ) {
            $.ajax( {
                url : base_url 
                    + "/wp-admin/admin-ajax.php",
                type : 'GET',
                cache : false,
                data : 'action=check_email_used&'
                    + Math.floor( ( Math.random() *100 ) +1 )
                    + '&email=' + email,
                success : function( result_email ) {
                    if ( parseInt( result_email ) == 0 ) {
                        $( ".result" ).html( '<span class="error">Email already used </span>' );
                    } else if ( parseInt( result_email ) == 1 ) {
                        $( ".result" ).html( '' );      
                        $( ".signup_div" ).hide();
                        $( ".signup_emergency_contact" ).show();
                    }
                }
            } );
        }
    }   
} );    

functions.php tiene

add_action('wp_ajax_check_user_name','check_user_name');
add_action('wp_ajax_nopriv_check_user_name','check_user_name');

add_action( 'wp_ajax_check_email_used','check_email_used' );
add_action( 'wp_ajax_nopriv_check_email_used','check_email_used' );
function check_user_name() {
    global $wpdb;

    $user_name = trim( $_GET['user_name'] );
    $MobTraining = new MobTraining();
    $table =trim( "{$wpdb->prefix}users" );
    $array_where['user_login'] = $user_name;
    $sql_fetch = $MobTraining->fetch( $table, $array_where );
    $row = $wpdb->get_results( $sql_fetch, ARRAY_A );
    if ( sizeof( $row ) != 0 ) {
        echo '0';
    } else {
        echo '1';
    }
    die();
}

function check_email_used() {
    global $wpdb;

    $email = trim( $_GET['email'] );
    $MobTraining = new MobTraining();
    $table = trim( "{$wpdb->prefix}users" );
    $array_where['user_email'] = $email;
    $sql_fetch = "SELECT * FROM $table WHERE `user_email`='$email'";
    $row = $wpdb->get_results( $sql_fetch, ARRAY_A );
    if ( sizeof( $row ) != 0 ) {
        echo '0';
    } else {
        echo '1';
    }
    die();
}

¿Cómo hacer que el código funcione en el servidor en línea?

Respuesta:

Lo que está experimentando (AJAX funciona localmente, pero no en el servidor) hay un problema de demora. A nivel local, todo funciona tan rápido que no puede ver su problema. En resumen, este es tu problema:

La devolución de llamada AJAX (A) se ejecuta> AJAX Callback (B) no sabe que tiene que esperar (A)> No puede ver el problema en su instalación local ya que (A) finalizó demasiado rápido.

Por lo tanto, debe encontrar una manera de decirle a su devolución de llamada (B) que debe esperar a (A). Así es cómo:

Registre scripts y mueva datos de PHP a JS

Regístrese, ponga en cola y localice sus datos de la manera correcta: envuélvalos en una función o método y conéctelos a wp_enqueue_scripts (público / temas), login_enqueue_scripts (contraseña / inicio de sesión / registro) o admin_enqueue_scripts . El uso de wp_localize_script() para mover datos de PHP a JS y hacerlos accesibles allí.

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
                ),
        ),
    );
}

Cómo usar jQuery AJAX de la manera correcta.

Hay varias funciones que puede usar: El $.ajax({}); predeterminado $.ajax({}); función o sus atajos $.post(); , $.getJSON(); etc.

Entonces, simplemente puede usar algo como lo siguiente: usando los métodos de objeto de success/fail .

( 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 || {} );

Si desea profundizar más y hacer las cosas realmente de la manera correcta , tendrá que usar el método de encadenamiento. (Todavía queda margen de mejora).

( 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 || {} );

Nota: Para obtener mejores ejemplos de la envoltura alrededor de la devolución de llamada, eche un vistazo a commonjs o AMD y sus diferencias.

Esperando otras respuestas AJAX

La parte interesante y más poderosa de todo el manejo de AJAX de jQuery (y otras bibliotecas) es cómo esperar hasta que A termine para luego iniciar B y su procesamiento. La respuesta es carga "diferida" y "promesas".

Agregaré un ejemplo rápido. Quizás deberías pensar en construir un objeto y separar cosas agregándolo a través de this. al objeto, pero por ejemplo, lo siguiente debería ser suficiente:

Ejemplo (A) Esto básicamente es como lo hago yo. Tendrás que llenar los bits tú mismo.

( 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 || {} );

Ejemplo (B) Nunca lo intenté así, pero debería funcionar también. Más fácil de leer, pero me gusta más $.when() resuelto promesas.

( 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 || {} );

Si desea profundizar aún más, lea los Documentos sobre deferred y then .

async/ await

EDITAR Como esta respuesta recibe bastante atención a lo largo de los años y ya tiene 8 años, eche un vistazo al siguiente fragmento.

Tenga en cuenta que async/await todavía se ocupa de Promises. Es solo azúcar sintética. También tenga en cuenta a qué se refiere this , cuando use funciones de mano corta como las que se ven en handlerB() .

Eso incluso funcionará con 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

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım