如何让jQuery等待Ajax调用完成后才返回?

我有一个需要login的服务器端function。 如果用户login,该function将成功返回1。 如果没有,该函数将返回login页面。

我想使用Ajax和jQuery来调用函数。 我所做的是用一个普通的链接提交请求,并在其上应用点击function。 如果用户没有login或function失败,我希望Ajax调用返回true,以便href触发。

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

我如何优雅地将用户redirect到login页面?

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

如果您不想立即返回$.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函数中处理响应。 这些函数只有在从服务器收到响应时才被调用。

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

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

底层的XMLHttpRequest对象(由jQuery用来发出请求)支持asynchronous属性。 将其设置为false 。 喜欢

 async: false 

不要将asynchronous设置为false,这通常是不好的devise,您可能需要考虑在操作未决时阻止UI。

这可以很好地实现与jQuery的承诺如下:

 // 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 (ie 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

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

例如,而不是返回true你可以这样做:

 window.location="appropriate page"; 

当成功函数被调用时,页面被redirect。