Вопрос или проблема
В чем дело?
JS ФУНКЦИЯ ‘custom.js’
function validate() {
var email = jQuery("#billingemail").val();
if (isValidEmailAddress(email)) {
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {"action": "custome_ajax_email_check", "guestemail": email },
success: function(data){
data = jQuery.parseJSON(data);
if(data.result) {
alert('Email существует');
return false;
} else {
alert('Email не существует');
return true;
}
}
});
} else {
return false;
}
}
JS ПО КЛИКУ ‘custom.js’
$('#mwb_logincoupon').on('click', '#validateguestemail', function (e) {
e.preventDefault();
validateemail = validate();
PHP AJAX
add_action( 'wp_ajax_custome_ajax_email_check', 'custome_ajax_email_check' );
add_action('wp_ajax_nopriv_custome_ajax_email_check', 'custome_ajax_email_check');
function custome_ajax_email_check(){
$email = $_POST['guestemail'];
// выполнение проверки
if ( email_exists($email) ) {
$response->result = true;
}
else {
$response->result = false;
}
echo( json_encode( $response));
wp_die();
}
Отладка скрипта показывает, что JS код заходит в функцию success
, вызывая даже alert('Email существует')
, но оператор return
в функции никогда не возвращается, поэтому validateemail
всегда возвращает undefined
. Почему?
По предложению @SallyCJ использовать await
, я создал эту новую функцию
async function doAjax(email) {
let result;
try {
result = await jQuery.ajax({
url: ajaxurl,
type: 'POST',
data: {"action": "custome_ajax_email_check", "guestemail": email }
});
return result;
} catch (error) {
console.error(error);
}
}
Теперь моя функция validate()
выглядит просто так
function validate() {
var email = jQuery("#billingemail").val();
if (isValidEmailAddress(email)) {
doAjax(email).then( (data) => ajaxCallResult(data) )
}
. . . . .
И, наконец
function ajaxCallResult(data){
data = jQuery.parseJSON(data);
. . . . . .
Это работает.. очень интересно, изучая await
, then
, асинхронные
и синхронные
вызовы и т. д.
.
Ответ или решение
Почему функция AJAX WP всегда возвращает undefined
?
Работа с AJAX в WordPress может стать довольно запутанной, особенно когда дело доходит до управления возвратом значений в асинхронных запросах. В данной ситуации возникает проблема, когда функция validate
возвращает undefined
, несмотря на то что AJAX-запрос успешно выполняется и обрабатывает ответы. Давайте разберем это поэтапно.
1. Понимание асинхронности
Функция validate
, написанная для валидации адреса электронной почты, делает AJAX-запрос через jQuery. Однако, поскольку AJAX является асинхронным, выполнение кода продолжится до завершения запроса, что приводит к ситуации, когда ваше return
из функции validate
всегда возвращает undefined
. Это происходит из-за того, что функция завершает свою работу, не дожидаясь результата запроса.
Пример кода, вызывающего проблему
function validate() {
var email = jQuery("#billingemail").val();
if (isValidEmailAddress(email)) {
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {"action": "custome_ajax_email_check", "guestemail": email },
success: function(data){
data = jQuery.parseJSON(data);
if(data.result) {
alert('Email Exists');
return false;
} else {
alert('Email Does Exists');
return true;
}
}
});
} else {
return false;
}
}
2. Использование async/await
для управления асинхронностью
Чтобы получить ожидаемое значение из AJAX-запроса, необходимо использовать подход, который позволяет работать с асинхронным выполнением, такие как async/await
. Это подходит для случаев, когда нам нужно дождаться выполнения асинхронной операции перед тем, как продолжить выполнение кода.
Ранее предложенное решение с использованием async/await
выглядит следующим образом:
async function doAjax(email) {
let result;
try {
result = await jQuery.ajax({
url: ajaxurl,
type: 'POST',
data: {"action": "custome_ajax_email_check", "guestemail": email },
});
return result; // Возвращаем результат после завершения запроса
} catch (error) {
console.error(error);
}
}
function validate() {
var email = jQuery("#billingemail").val();
if (isValidEmailAddress(email)) {
doAjax(email).then((data) => ajaxCallResult(data));
}
}
3. Обработка результата
После выполнения AJAX-запроса в функции doAjax
, мы передаем результат в ajaxCallResult
, которая обрабатывает данные.
function ajaxCallResult(data) {
data = jQuery.parseJSON(data);
if(data.result) {
alert('Email Exists');
} else {
alert('Email Does Not Exists');
}
}
Вывод
С введением async/await
вы сможете лучше управлять асинхронными вызовами в JavaScript и избегать проблем с возвратом значений из функций. Данный подход не только решает текущую проблему, но и улучшает читаемость и поддержку кода в будущем.
Таким образом, чтобы избежать проблемы с возвращением undefined
в функции AJAX, необходимо использовать асинхронный подход, что позволит вам более эффективно обрабатывать данные, полученные из серверных вызовов. Не забывайте поддерживать код в согласованности с основами JavaScript и jQuery.