Jquery ajax синхронный вызов beforeSend

У меня есть функция, называемая:

function callAjax(url, data) {
 $.ajax(
   {
     url: url, // same domain
     data: data,
     cache: false,
     async: false, // use sync results
     beforeSend: function() {
       // show loading indicator
     },
     success: function() {
       // remove loading indicator 
     }
   }
  );
}

В коде я вызываю "callAjax" X количество раз, и я хочу синхронно обновлять данные. Это сделано так, как ожидалось, но одна проблема: загрузочный элемент не отображается в функции beforeSend. Если я вернусь к async к true, он работает, но обновления не выполняются синхронно.

Я пробовал несколько вещей без успеха. Я попытался поставить индикатор загрузки перед вызовом ajax следующим образом:

function callAjax(url, data) {
  // show loading div

  $.ajax(
    {
      // same as above
    }
   );
}

Но по какой-то причине он не хочет показывать индикатор загрузки. Я замечаю странное поведение, когда я добавляю "предупреждение" в beforeSend, и в этом случае появляется индикатор загрузки, но я скорее не выхожу из окна сообщений.

Есть идеи?

Ответ 1

Создание синхронного вызова похоже на то, что он помещает флажок "alert()". Некоторые браузеры останавливают то, что они делают, полностью, пока не будет получен ответ HTTP.

Таким образом, в вашем коде после того, как начнется ваш вызов функции "$.ajax()", ничего произойдет до тех пор, пока ответ не будет получен, а следующее, что касается вашего кода, будет обработчик "success".

Как правило, если вы не уверены в своем сервере, гораздо лучше использовать асинхронные вызовы. Когда вы это делаете, браузер немедленно возвращается к своей работе и просто слушает в фоновом режиме для ответа HTTP. Когда ответ будет получен, ваш обработчик успеха будет вызван.

Ответ 2

Когда вы делаете блокирующий ввод-вывод, программа останавливается до тех пор, пока не будет получен вход, в словах JS при выполнении синхронного вызова программа останавливается, а окно браузера зависает (без рисования не может быть сделано) до получения ответа, В большинстве случаев можно избежать синхронных вызовов и любых блокирующих операций ввода-вывода. Однако представьте, что вы делаете индикатор выполнения в java или любом другом языке программирования, вы должны создать другой поток, чтобы контролировать индикатор выполнения, я думаю.

Одна вещь, которую вы можете попробовать в своем случае, - вызвать вызов ajax после задержки

//loading div stuff, 
//if your doing some animation here make sure to have Sufficient 
//time for it. If its just a regular show then use a time delay of 100-200
setTimeout( ajaxCall, 500 );

EDIT ajaxcall в setTimeout, Пример

Ответ 3

Это то, что вы ищете -.ajaxStart()

Он будет запущен, когда произойдет какое-либо событие ajax

http://api.jquery.com/ajaxStart/

Они даже дают конкретный пример, похожий на то, что вы пытаетесь выполнить:

 $("#loading").ajaxStart(function(){
   $(this).show();
 });

Затем вы можете использовать функцию .ajaxStop()

$("#loading").ajaxStop(function(){
      $(this).hide();
});