我一直盯着这个问题几个小时。我有一个样板代码示例我正在处理如下
$('.save_stuff').on("click", function(e)
{
e.preventDefault();
e.stopPropagation();
preprocessAddProvisioning();
var mac = $('#c_mac_address').val();
var make = $('#c_make').html();
var model = $('#c_model option:selected').text();
var regex = /[a-zA-Z0-9]{12}/g;
if (mac.match(regex) && validateNewDevice())
{
$.ajax({
url: "/SomeUrl",
dataType: 'json',
type: 'POST',
async: false,
data:
{
mac: mac,
model: model,
make: make
},
success: function(data)
{
if (data.success)
{
$('#someValue').hide();
$('#modalNewDevice').modal('hide');
if (someValue !== undefined && !someValue.snom_mac_success)
{
window.location.href = "/SomeUrl?id="+someValue.newId+"&someValue=false";
}
else
{
window.location.href = "/SomeUrl?id="+data.newId;
}
}
else
{
$('#c_msg').html(data.msg);
$('#c_msg').closest('.form-group').addClass('has-error');
}
},
error: function()
{
}
});
}
});
使用名为being的方法;
function preprocessAddProvisioning()
{
$('#mac_load').show('fast');
}
有人可以告诉我为什么,async:false,停止preprocessAddProvisioning()被调用?我在想到ajax请求的上下文时意识到这是有意义的,而不是在听者的上下文中。
非常感谢
答案 0 :(得分:3)
AJAX请求不会阻止preprocessAddProvisioning()
执行。它会阻止UI线程并阻止窗口更新,因此显示 preprocessAddProvisioning()
没有做任何事情。最重要的是,.show('fast')
使用动画,这不仅需要一次UI更新,而且需要在几毫秒的时间内完成。随着JavaScript执行的停止,jQuery甚至不能尝试执行该动画,更不用说让窗口显示它了。
由于UI线程被阻止而无法更新窗口的演示:
document.getElementsByTagName('input')[0].addEventListener('click', function (){
var div = document.getElementsByTagName('div')[0];
// hide div
div.style.display = 'none';
// block thread for 3 seconds
var dt = new Date();
while (new Date() - dt < 3000) {}
});
&#13;
div { width: 100px; height: 100px; background-color: red; }
&#13;
<div>
</div>
<input type="button" value="Click me" />
&#13;
故事的道德:不要使用async: false
,但如果你绝对不得不这样做,你可以使用超时来确保你的装载机在之前完成的显示AJAX请求:
setTimeout(function () {
makeTheAjaxRequest();
}, 500);
请记住,如果您的加载器涉及动画.gif或类似内容,则.gif将在UI线程被阻止时被冻结。
更精确的选择是在动画完成后使用complete
上的.show()
回调继续执行您的步骤,但所有可能完成的事情都是意大利面条你的代码。真正的答案是不使用async: false
。