Функция WP Ajax всегда возвращает undefined

Вопрос или проблема

В чем дело?

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.

Оцените материал
Добавить комментарий

Капча загружается...