Execută o cerere AJAX după ce o altă cerere AJAX s-a finalizat
Un fișier JS face un apel ajax. În cadrul succesului acestui apel ajax se face un alt apel AJAX. Al doilea apel verifică dacă emailul a fost deja înregistrat. Dacă a fost înregistrat, atunci al doilea apel AJAX nu primește date returnate, așa cum se arată în Firebug și consola Chrome în acest caz. Dar același cod funcționează perfect în localhost în timp ce problema menționată apare DOAR pe serverul online.
Pagina găzduită este la http://twmobilefitness.com/signup/
. Problema apare când faci clic pe link-ul 'Register Now' de la final. Trebuie să te înregistrezi de două ori cu aceeași adresă de email dacă vrei să reproduci 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">Numele de utilizator nu este disponibil </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">Emailul este deja folosit </span>' );
} else if ( parseInt( result_email ) == 1 ) {
$( ".result" ).html( '' );
$( ".signup_div" ).hide();
$( ".signup_emergency_contact" ).show();
}
}
} );
}
}
} );
functions.php
are
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();
}
Cum pot face codul să funcționeze pe serverul online?

Ceea ce experimentați (AJAX funcționează local, dar nu pe server) este o problemă de întârziere. Local totul funcționează atât de repede, încât nu puteți vedea problema. Pe scurt, aceasta este problema dumneavoastră:
Callback-ul AJAX (A) se execută > Callback-ul AJAX (B) nu știe că trebuie să aștepte după (A) > Nu puteți vedea problema în instalarea locală, deoarece (A) se termină prea repede.
Așadar, trebuie să găsiți o modalitate de a-i spune Callback-ului (B) că trebuie să aștepte după (A). Iată cum:
Înregistrați scripturile și mutați datele din PHP în JS
Înregistrați și încărcați corect datele localizate: Înfășurați-le într-o funcție sau metodă și conectați-o la wp_enqueue_scripts
(public/teme), login_enqueue_scripts
(parolă/autentificare/înregistrare) sau admin_enqueue_scripts
. Apoi utilizați wp_localize_script()
pentru a muta datele din PHP în JS și a le face accesibile acolo.
add_action( 'admin_enqueue_scripts', 'wpse118772jsObject' );
function wpse118772jsObject()
{
$scriptHandle = 'custom-script-name';
// Ar trebui să fie împărțit în funcții sau metode separate
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(
// date personalizate aici
),
),
);
}
Cum să utilizați corect jQuery AJAX.
Există mai multe funcții pe care le puteți utiliza: funcția implicită $.ajax({});
sau scurtăturile acesteia $.post();
, $.getJSON();
, etc.
Așadar, puteți utiliza pur și simplu ceva de genul următor - folosind metodele obiectului success/fail
.
( function( $, plugin ) {
"use strict";
$.ajax( {
url : plugin.ajaxURl,
data : {
// alte date
},
// Presupunem că răspundeți cu un wp_send_json_success/error() corespunzător în Callback-ul PHP.
dataType : "json",
// Transformarea cererii este posibilă aici.
beforeSend : function( xhr ) {
// Exemplu:
// xhr.overrideMimeType( 'application/json' );
},
// Gestionare efectivă
success : function( data, textStatus, jqXHR ) {
// Manipulați transformarea datelor sau manipularea DOM aici.
},
error : function( jqXHR, textStatus, errorThrown ) {
// silent: Înregistrați eroarea
console.info( errorThrown );
// loud: Aruncați excepție
throw errorThrown;
}
} );
} )( jQuery, pluginObject || {} );
Dacă doriți să intrați mai în profunzime și să faceți lucrurile într-adevăr corect, va trebui să utilizați înlănțuirea metodelor. (Mai este loc pentru îmbunătățiri).
( function( $, plugin ) {
"use strict";
$.ajax( {
url : plugin.ajaxURl,
data : {
// alte date
},
} )
.done( function( data ) {
// Gestionați doar răspunsurile de succes
} )
.fail( function( reason ) {
// Gestionați doar erorile
console.debug( reason );
} )
.always( function( data, textStatus, response ) {
// Dacă doriți să separați manual lucrurile
// response devine errorThrown/reason SAU jqXHR în caz de succes
} )
.then( function( data, textStatus, response ) {
// În cazul în care lucrați cu un deferred.promise, utilizați această metodă
// Din nou, va trebui să separați manual succesul/eroarea
} );
} )( jQuery, pluginObject || {} );
Notă: Pentru exemple mai bune ale învelișului în jurul callback-ului, consultați commonjs sau AMD și diferențele dintre ele.
Așteptarea altor răspunsuri AJAX
Partea interesantă - și cea mai puternică a întregii gestionări AJAX în jQuery (și alte biblioteci) - este cum să așteptați până când A se termină pentru a începe apoi B și procesarea acestuia. Răspunsul este încărcarea "amânată" și "promisiunile".
Voi adăuga un exemplu rapid. Ar trebui să vă gândiți poate la construirea unui obiect și separarea lucrurilor prin adăugarea lor via this.
la obiect, dar pentru un exemplu, următoarele ar trebui să fie suficiente:
Exemplu (A) Acesta este în principiu cum o fac eu. Va trebui să completați detaliile singur.
( function( $, plugin ) {
"use strict";
$.when(
$.ajax( {
url : pluginURl,
data : { /* ... */ }
} )
.done( function( data ) {
// Al doilea apel s-a terminat
} )
.fail( function( reason ) {
console.info( reason );
} )
)
// Din nou, ați putea utiliza .done(). Consultați documentația jQuery.
.then(
// Succes
function( response ) {
// A avut succes
// În cazul mai multor cereri, ambele trebuie să aibă succes
},
// Eșec
function( resons ) {
// A generat o eroare
// în cazul mai multor erori, aruncă prima
},
);
} )( jQuery, pluginObject || {} );
Exemplu (B) Nu am încercat niciodată așa, dar ar trebui să funcționeze și așa. Mai ușor de citit, dar mie îmi place mai mult rezolvarea cu $.when()
.
( function( $, plugin ) {
"use strict";
$.ajax( {
url : plugin.ajaxURl,
data : {
// alte date
}
} )
.done( function( data ) {
// Gestionați doar răspunsurile de succes
} )
.fail( function( reason ) {
console.info( reason );
} )
// Promisiune finalizată:
.then( function( data ) {
$.ajax( {
url : pluginURl,
data : { /* ... */ }
} )
.done( function( data ) {
// Al doilea apel s-a terminat
} )
.fail( function( reason ) {
console.info( reason );
} );
} );
} )( jQuery, pluginObject || {} );
Dacă doriți să intrați și mai în profunzime, citiți documentația despre deferred
și then
.
async/ await
EDITARE Deoarece acest răspuns primește destul de multă atenție de-a lungul anilor și are deja 8 ani, vă rugăm să consultați următorul fragment.
Rețineți că async/await
încă se ocupă de Promisiuni. Este doar zahăr sintetic. De asemenea, rețineți la ce se referă this
când utilizați funcții prescurtate, cum se vede în handlerB()
.
Asta va funcționa chiar și cu jQuery.
( function( $, plugin ) {
const handlerA = async function( plugin ) {
try {
let res = await $.ajax( {
url : plugin.ajaxURl,
data : { /* unele date */ }
} )
.done( function( data ) {
// Gestionați doar răspunsurile de succes
} )
.fail( function( reason ) {
console.error( reason );
} )
return res;
} catch ( err ) {
console.error( err )
}
}
const handlerB = async data => { /* încă o cerere AJAX */ }
// Executați
// …așteptați…
let $resultA = await handlerA( plugin )
// Acum executați B
let $resultB = await handlerB( $resultA )
// Faceți ceva cu $resultB
} )( jQuery, pluginObject || {} );

de fapt, nu folosesc niciun plugin. Doar un simplu apel AJAX în WordPress. În legătură cu problema de întârziere a serverului - Firebug arată că cererea AJAX s-a încheiat, dar nu a primit niciun date. Lasă-mă să analizez mai profund răspunsul tău.

@IstiaqueAhmed Descrierea de mai sus nu este menită să fie vreun plugin. Doar o bază pentru a-ți scrie propriul plugin (sau, în cazul în care nu-ți pasă de separarea preocupărilor, propria ta temă).

Mulțumesc, acest lucru a fost de mare ajutor într-un proiect recent. Deja am votat demult ;-) De asemenea, voiam doar să menționez că funcțiile de callback success
, error
, complete
sunt acum depreciate în favoarea celor de tip promise menționate în răspuns.

@birgire Te rog să [editezi] răspunsul. Am verificat și doar prima parte este acum învechită. Mulțumesc anticipat și mulțumesc pentru cuvintele frumoase :)

@kaiser în exemplele 'Așteptând alte răspunsuri AJAX' A și B, unde sunt exact cele de-al doilea apeluri ajax? Nu văd un al doilea apel ajax în Exemplul A.

Pentru a executa o cerere AJAX după finalizarea altei cereri AJAX, trebuie să adăugați următoarea linie,
async: false,
adică, trebuie să adăugați async: false
în metoda ajax, după cum urmează,
$.ajax( { url : base_url+"/wp-admin/admin-ajax.php", type : 'GET', async: false,
