jAlert не отображается с синхронизацией jQuery ajax

Я использую подключаемый модуль jQuery Alert Dialogs (http://abeautifulsite.net/, версия 1.1) и jQuery v1.6.1. . Протестировано в версиях IE 11 и Chrome 41.0.x. Есть тестовый код:

    var t = (new Date()).getTime();
    jAlert('Test message');
    console.log('Alert displayed, d=' + ((new Date()).getTime() - t));
    console.log('  Alert visible: ' + $('#popup_panel').is(":visible") + ', Overlay visible: ' + $('#popup_overlay').is(":visible") + ', d=' + ((new Date()).getTime() - t));

    $.ajax({
        url: 'http://ip.jsontest.com/',
        data: { },
        type: 'GET',
        async: false,
        complete: function() {
            console.log('Ajax complete, d=' + ((new Date()).getTime() - t));
            $.alerts._hide();
            console.log('  Alert visible: ' + $('#popup_panel').is(":visible") + ', Overlay visible: ' + $('#popup_overlay').is(":visible") + ', d=' + ((new Date()).getTime() - t));
        }
    });

И вывод консоли:

Alert displayed, d=8
  Alert visible: true, Overlay visible: true, d=9
Ajax complete, d=276
  Alert visible: false, Overlay visible: false, d=281

Моя проблема в том, что когда я устанавливаю для $.ajax async значение false, окно предупреждения не отображается. Все работает нормально, когда для async установлено значение true. Я знаю, что означает async: false. Я использовал его в своей форме для отправки данных. Пока выполняется отправка данных, я хочу отображать и предупреждать окно с чем-то вроде «Выполняется операция ...» и блокировать любой пользовательский ввод (щелчок мышью, клавиша Enter на клавиатуре и т. д.). В некоторых местах моего приложения это работает, в других нет, и я не могу понять, почему. Есть ли способ убедиться, что изменения пользовательского интерфейса внесены до фактического вызова ajax?


person Marius    schedule 16.04.2015    source источник


Ответы (1)


Из bugs.jquery.com:

Если я покажу сообщение (например, "Загрузка") ДО того, как я сделаю вызов AJAX, я ожидаю, что оно отобразится.

Код перед вызовом выполняется, но это не значит, что вы сразу увидите результат. Если вызов действительно и полностью синхронен, обновление окна может произойти только после завершения вызова $.ajax. Это не будет отличаться от:

Если вы действительно хотите использовать async:false ajax, вы можете попробовать деформировать его с помощью setTimeOut, чтобы позволить браузеру выполнить код перед ним и увидеть изменения до того, как браузер зависнет.

var t = (new Date()).getTime();
    jAlert('Test message');
    console.log('Alert displayed, d=' + ((new Date()).getTime() - t));
    console.log('  Alert visible: ' + $('#popup_panel').is(":visible") + ', Overlay visible: ' + $('#popup_overlay').is(":visible") + ', d=' + ((new Date()).getTime() - t));

// do async call
setTimeout(function () {
   $.ajax({
        url: 'http://ip.jsontest.com/',
        data: { },
        type: 'GET',
        async: false,
        complete: function() {
            console.log('Ajax complete, d=' + ((new Date()).getTime() - t));
            $.alerts._hide();
            console.log('  Alert visible: ' + $('#popup_panel').is(":visible") + ', Overlay visible: ' + $('#popup_overlay').is(":visible") + ', d=' + ((new Date()).getTime() - t));
        }
    });
}, 20);
person semirturgay    schedule 16.04.2015
comment
Хорошая точка зрения. Я подозревал это. setTimeout не кажется очень надежным решением. Я думаю, что фактическое время ожидания зависит от производительности браузера и иногда может быть слишком маленьким. Я думаю, что я собираюсь использовать асинхронный вызов ajax и использовать некоторый флаг, что отправка данных выполняется, и любые повторяющиеся отправки следует игнорировать. - person Marius; 16.04.2015