@aornos

Заставить ajax работать синхронно?

Доброе время суток
Заполняем форму, перед сабмитом проверяем. Одно поле в форме, должно быть уникальным. Его отправляем ajax`ом скрипту, скрипт возвращает true или false. Если false, то поле маркируем как ошибочное и не сабмитим. Кажется просто?
Проблема в том что запрос выполняется асинхронно, поле помечается как ошибочное, т.к. результат undefined - не успевает обработаться запрос. В консоле ошибка: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check xhr.spec.whatwg.org.
Но так же выводит что:
'translit check is: true';
'value is: выводит значение поля';
'result is: undefined'
вот код:
//валидатор
result = checkTranslit($('#translit').val());
    if (result  !== 'true') {
        errorArray.push("translit");//кладем поле в массив с ошибками
        console.log('value is: ' + $('#translit').val() + '\n');
        console.log('result is: ' + result + '\n');
    } 

//запрос 
function checkTranslit(translit){
    $.ajax({
        url: 'http://site.com/scripts/checkTranslit.php',
        data: {'translit': translit},
        type: 'POST',
        dataType: 'json',
        async: false,
        success: function(data){
            answer = JSON.stringify(data);            
            console.log('translit check is: ' + answer.result + '\n');    
            return answer.result;
        },
        error: function(error){
            err = JSON.stringify(error);
           console.log('error is: ' + err.result + '\n');  
            return err.result;
        }
    });

}


Как заставить запрос работать синхронно? Или блокировать ГУЙ на время выполнения? Куда копать?
  • Вопрос задан
  • 5034 просмотра
Пригласить эксперта
Ответы на вопрос 5
@serega_kaktus
Программист-самоучка, фрилансер
тут варианта 2 - написать свой js движок, в котором ajax будет синхронный, продвинуть этот движок во все браузеры, параллельно поправить стандарты ActionScript. До даже тогда ваш говнокод не заработает, потому что надо хотя бы какое-то значение возвращать из функции checkTranslit.
Ну или можно просто запомнить одно простое правило - если нужно выполнить какое-то действие после завершения ajax запроса, то это действие должно выполнятся в success колбэке.
Перепишите код
//валидатор
checkTranslit($('#translit').val());
    

//запрос 
function checkTranslit(translit){
    $.ajax({
        url: 'http://site.com/scripts/checkTranslit.php',
        data: {'translit': translit},
        type: 'POST',
        dataType: 'json',
        async: false,
        success: function(data){
          if (!answer.result) {
            errorArray.push("translit");//кладем поле в массив с ошибками
            console.log('value is: ' + $('#translit').val());
            console.log('result is: ' + answer.result);
          } 
        },
        error: function(error){
           console.log('error is: ' + error + '\n');  
            return error;
        }
    });

}

Если у вас dataType: json, зачем вы какие-то манипуляции с ними в колбэках проводите? Скрипт на сервере должен возвращать json, а в колбэке уже будет десерализованный объект
Ответ написан
Комментировать
Groov3
@Groov3
Full stack web developer/Performance marketing
Ахаха. Ну в настройках JS можно задать синхронность, или асинхронность выполнения на клиенте AJAX, тупо задавая такой приоритет при загрузке и выполнении, если речь не о деферред. Сами свой код читайте.
Ответ написан
jqXHR-объекты, возвращаемые методом jQuery.ajax() реализуют интерфейс Promise, предоставляя им все свойства, методы и поведение Promise. Метод jqXHR.done() интерфейса Promise пришел на смену jqXHR.success().
api.jquery.com/jQuery.ajax
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.

Исходя из этого можно получать jqXHR-объект и слушать его события.
Пример
Ответ написан
Комментировать
@unabl4
ruby on rails web dev
Не надо делать синхронные запросы. Это плохая практика, потому что js - событийный однопоточный язык программирования, и он очень не рад когда ему подсовывают что-то блокирующее. Не надо так.
Читайте про каллбэк функции и так далее.
Ответ написан
Комментировать
IonDen
@IonDen
JavaScript developer. IonDen.com
В вашем случае лучше всего блокировать гуй. Делается это например так:

1. Оборачиваем форму в контейнер
2. Кладем в конец этого контейнера новый див .blocker, примерно такой
.blocker {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: rgba(255, 255, 255, 0.5);
}

этот див займёт всё пространство поверх вашей формы и сделает её полупрозрачной (можно так же какой нибудь гиф-прелоадер добавить в центр) + заблокирует к ней доступ.
3. При запуске аякс запроса делаем этот див видимым.
4. По окончании запроса внутри коллбэка success прячем его.
5. Вот и получилась блокировка GUI на время запроса.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы