Браузер запускает JavaScript и выполняет рендеринг страниц в одном и том же потоке, поэтому во время работы JS перерисовки не произойдет. Это означает, что весь цикл for завершится, и сообщение о состоянии будет установлено как «Готово!» до страница обновляется.
В случае, если асинхронность истинна, все Ajax-запросы изначально ставятся в очередь, а для сообщения устанавливается значение «Готово!» и затем ответы обрабатываются позже асинхронно. В случае, если для асинхронного режима установлено значение false, запросы Ajax выполняются по одному за раз без каких-либо дополнительных действий до тех пор, пока не поступит ответ. В любом случае браузер никогда не получает возможности отобразить сообщения «Я делаю ...».
Вместо использования цикла вы можете инициировать каждый последующий вызов из полного (или успешного) обратного вызова Ajax:
var tds = ["0", "1", "2", "3", "4", "5", "6"];
function doNextAjax(i) {
if (i < tds.length) {
jQuery("#notification-bar").html('I am doing ' + tds[i]);
jQuery.ajax({
url: "/ajax_json_echo/",
type: "POST",
timeout: 10000,
data: tds[i],
success: function(response) {
},
error: function(x, t, m) {
},
complete: function() {
doNextAjax(i + 1);
}
});
} else {
jQuery("#notification-bar").html("Done!");
}
}
doNextAjax(0);
Каждый раз, когда вызывается doNextAjax()
, он обновляет сообщение о состоянии и делает один Ajax-запрос, и все. Когда функция выходит из браузера, у нее появляется возможность повторно выполнить рендеринг и фактически показать это сообщение. Затем, когда завершается полный обратный вызов, он снова вызывает функцию для следующего элемента. Когда ничего не осталось, он устанавливает "Готово!" сообщение.
Обратите внимание, что использование полного обратного вызова для запуска следующего вызова Ajax означает, что он будет продолжаться даже в случае сбоя определенного запроса. Если вы хотите остановиться на ошибке, вы можете избавиться от полного обработчика и переместить doNextAjax(i+1)
в обратный вызов успеха.