首页 文章

如何让jQuery在返回之前等待Ajax调用完成?

提问于
浏览
213

我有一个需要登录的服务器端功能 . 如果用户已登录,则该功能将在成功时返回1 . 如果没有,该函数将返回登录页面 .

我想使用Ajax和jQuery调用该函数 . 我所做的是使用普通链接提交请求,并在其上应用单击功能 . 如果用户未登录或函数失败,我希望Ajax调用返回true,以便href触发 .

但是,当我使用以下代码时,该函数在Ajax调用完成之前退出 .

如何将用户正常重定向到登录页面?

$(".my_link").click(
    function(){
    $.ajax({
        url: $(this).attr('href'),
        type: 'GET',
        cache: false,
        timeout: 30000,
        error: function(){
            return true;
        },
        success: function(msg){ 
            if (parseFloat(msg)){
                return false;
            } else {
                return true;
            }
        }
    });
});

5 回答

  • 310

    如果您不希望立即返回 $.ajax() 函数,请将 async 选项设置为 false

    $(".my_link").click(
        function(){
        $.ajax({
            url: $(this).attr('href'),
            type: 'GET',
            async: false,
            cache: false,
            timeout: 30000,
            error: function(){
                return true;
            },
            success: function(msg){ 
                if (parseFloat(msg)){
                    return false;
                } else {
                    return true;
                }
            }
        });
    });
    

    但是,我会注意到这与AJAX的观点相反 . 此外,您应该在 errorsuccess 函数中处理响应 . 只有在从服务器收到响应时才会调用这些函数 .

  • 34

    底层的XMLHttpRequest对象(由jQuery用于发出请求)支持异步属性 . 将其设置为 false . 喜欢

    async: false
    
  • 28

    如果您编写 success 函数来加载适当的页面而不是返回 truefalse ,我认为事情会更容易 .

    例如,您可以执行以下操作,而不是返回 true

    window.location="appropriate page";
    

    这样,当调用成功函数时,页面被重定向 .

  • 19

    我没有使用 $.ajax 而是 $.post$.get 函数,所以如果我需要等待响应,我会使用:

    $.ajaxSetup({async: false});
    $.get("...");
    
  • 9

    您可能需要考虑在操作挂起时阻止UI,而不是将async设置为false(这通常是错误的设计) .

    使用jQuery promise可以很好地实现这一点,如下所示:

    // same as $.ajax but settings can have a maskUI property
    // if settings.maskUI==true, the UI will be blocked while ajax in progress
    // if settings.maskUI is other than true, it's value will be used as the color value while bloking (i.e settings.maskUI='rgba(176,176,176,0.7)'
    // in addition an hourglass is displayed while ajax in progress
    function ajaxMaskUI(settings) {
        function maskPageOn(color) { // color can be ie. 'rgba(176,176,176,0.7)' or 'transparent'
            var div = $('#maskPageDiv');
            if (div.length === 0) {
                $(document.body).append('<div id="maskPageDiv" style="position:fixed;width:100%;height:100%;left:0;top:0;display:none"></div>'); // create it
                div = $('#maskPageDiv');
            }
            if (div.length !== 0) {
                div[0].style.zIndex = 2147483647;
                div[0].style.backgroundColor=color;
                div[0].style.display = 'inline';
            }
        }
        function maskPageOff() {
            var div = $('#maskPageDiv');
            if (div.length !== 0) {
                div[0].style.display = 'none';
                div[0].style.zIndex = 'auto';
            }
        }
        function hourglassOn() {
            if ($('style:contains("html.hourGlass")').length < 1) $('<style>').text('html.hourGlass, html.hourGlass * { cursor: wait !important; }').appendTo('head');
            $('html').addClass('hourGlass');
        }
        function hourglassOff() {
            $('html').removeClass('hourGlass');
        }
    
        if (settings.maskUI===true) settings.maskUI='transparent';
    
        if (!!settings.maskUI) {
            maskPageOn(settings.maskUI);
            hourglassOn();
        }
    
        var dfd = new $.Deferred();
        $.ajax(settings)
            .fail(function(jqXHR, textStatus, errorThrown) {
                if (!!settings.maskUI) {
                    maskPageOff();
                    hourglassOff();
                }
                dfd.reject(jqXHR, textStatus, errorThrown);
            }).done(function(data, textStatus, jqXHR) {
                if (!!settings.maskUI) {
                    maskPageOff();
                    hourglassOff();
                }
                dfd.resolve(data, textStatus, jqXHR);
            });
    
        return dfd.promise();
    }
    

    有了这个你现在可以做:

    ajaxMaskUI({
        url: url,
        maskUI: true // or try for example 'rgba(176,176,176,0.7)'
    }).fail(function (jqXHR, textStatus, errorThrown) {
        console.log('error ' + textStatus);
    }).done(function (data, textStatus, jqXHR) {
        console.log('success ' + JSON.stringify(data));
    });
    

    UI将阻塞,直到ajax命令返回

    jsfiddle

相关问题