У вас есть пара проблем в вашем коде. Во-первых, в своем «ложном» AJAX-запросе вы используете цикл. Это синхронная операция и причина проблемы, препятствующей обновлению пользовательского интерфейса;цикл останавливает выполнение любой другой операции (т. е. обновление элемента в DOM). Следовательно, он обновляется только после завершения цикла.
Во-вторых, как только вы действительно начнете использовать AJAX-запрос в функции loadData()
, вы столкнетесь с проблемами с синхронностью, поскольку ожидаете логическое возвращаемое значение. указать, работал ли запрос AJAX. Это невозможно с асинхронной логикой. Таким образом, вам нужно работать с обещаниями и / или обратными вызовами.
Для этого вам нужно вернуть обещание из $.ajax()
в функции loadData()
. Затем вы можете использовать методы done()
и fail()
для обновления DOM на основе результата запроса. Это должно выглядеть примерно так:
$('#btnLoad').click(function() {
showMsg('Loading, please wait ...', 'info');
loadData().done(function() {
showMsg('Loaded', 'info');
}).fail(function() {
showMsg('Error', 'warn');
});
});
function loadData() {
return $.ajax({
url: '/yourpage',
data: {
foo: 'bar'
}
});
}
Ниже приведен рабочий пример, в котором смоделирован запрос AJAX путем ручного разрешения отложенного объекта через 3 секунды. Вы можете видеть, что сообщение о загрузке теперь отображается правильно из-за исправленного использования асинхронной логики.
$(document).ready(function() {
function showMsg(msg, type) {
$('#msgBox')
.removeClass("ais-card-message-info ais-card-message-warn")
.addClass("ais-card-message-" + type)
.text(msg)
.show();
}
$('#btnLoad').click(function() {
showMsg('Loading, please wait ...', 'info');
loadData().done(function() {
showMsg('Loaded', 'info');
}).fail(function() {
showMsg('Error', 'warn');
});
});
function loadData() {
// mock AJAX request, just for this demo
var deferred = jQuery.Deferred();
setTimeout(function() {
deferred.resolve();
}, 3000);
return deferred;
}
});
.ais-card-message {
padding: 6px;
margin-top: 6px;
margin-bottom: 6px;
text-align: left;
}
.ais-card-message-info {
background-color: lightskyblue;
}
.ais-card-message-warn {
background-color: lightpink;
}
<div id="title">
<p>Message "Loading, please wait ..." should appear below when button clicked. Followed by either "Error" or "Loaded" after a short delay.</p>
</div>
<div id="data">Data will be loaded here</div>
<div id="msgBox" class="ais-card-message">Messages should display here</div>
<div><button id="btnLoad">Load</button></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>