为什么async:false在侦听器中,停止所有执行



我已经盯着这个问题了几个小时。我有一个样本样本,如下所示

$('.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()
            {
            }
        });
    }
});

使用称为;

的方法
function preprocessAddProvisioning()
{
    $('#mac_load').show('fast');
}

有人可以告诉我为什么,async:false,停止称为preprocessaddrovisioning()?我意识到在思考Ajax请求的上下文时,这是含义的,而不是听众的上下文。

非常感谢

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) {}
});
div { width: 100px; height: 100px; background-color: red; }
<div>
</div>
<input type="button" value="Click me" />

故事的寓意:不要使用async: false,但是如果您绝对需要,则可以使用超时来确保加载程序在之前完成 您提出AJAX请求:>

setTimeout(function () {
    makeTheAjaxRequest();
}, 500);

请记住,如果您的装载机涉及动画.gif或类似的东西,则在UI线程被阻止时,.GIF将被冷冻。

一个更精确的选项是,一旦动画完成,使用.show()上的complete回调继续执行步骤,但是所有可能完成的事情都是在意大利面对您的代码上意大利面。真正的答案是不使用async: false

最新更新