如何让 jQuery 在返回之前等待 Ajax 调用完成?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/755885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I make jQuery wait for an Ajax call to finish before it returns?
提问by Hobhouse
I have a server side function that requires login. If the user is logged in the function will return 1 on success. If not, the function will return the login-page.
我有一个需要登录的服务器端功能。如果用户登录,该函数将在成功时返回 1。如果没有,该函数将返回登录页面。
I want to call the function using Ajax and jQuery. What I do is submit the request with an ordinary link, with a click-function applied on it. If the user is not logged in or the function fails, I want the Ajax-call to return true, so that the href triggers.
我想使用 Ajax 和 jQuery 调用该函数。我所做的是使用普通链接提交请求,并在其上应用点击功能。如果用户未登录或函数失败,我希望 Ajax 调用返回 true,以便触发 href。
However, when I use the following code, the function exits before the Ajax call is done.
但是,当我使用以下代码时,该函数会在 Ajax 调用完成之前退出。
How can I redirect the user gracefully to the loginpage?
如何优雅地将用户重定向到登录页面?
$(".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;
}
}
});
});
回答by cgp
If you don't want the $.ajax()
function to return immediately, set the async
option to false
:
如果您不希望$.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;
}
}
});
});
But, I would note that this would be counter to the point of AJAX. Also, you should be handling the response in the error
and success
functions. Those functions will only be called when the response is received from the server.
但是,我会注意到这与 AJAX 的观点背道而驰。此外,您应该处理error
和success
函数中的响应。只有在从服务器收到响应时才会调用这些函数。
回答by MilMike
I am not using $.ajax
but the $.post
and $.get
functions, so if I need to wait for the response, I use this:
我使用$.ajax
的不是$.post
和$.get
函数,所以如果我需要等待响应,我使用这个:
$.ajaxSetup({async: false});
$.get("...");
回答by idrosid
The underlying XMLHttpRequest object (used by jQuery to make the request) supports the asynchronous property. Set it to false. Like
底层 XMLHttpRequest 对象(由 jQuery 用于发出请求)支持异步属性。将其设置为false。喜欢
async: false
回答by kofifus
Instead of setting async to false which is usually bad design, you may want to consider blocking the UI while the operation is pending.
与其将 async 设置为 false(这通常是糟糕的设计),您可能需要考虑在操作挂起时阻止 UI。
This can be nicely achieved with jQuery promises as follows:
这可以通过 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 (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();
}
with this you can now do:
有了这个,你现在可以做:
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));
});
And the UI will block until the ajax command returns
并且 UI 将阻塞,直到 ajax 命令返回
see jsfiddle
回答by samuelagm
I think things would be easier if you code your success
function to load the appropriate page instead of returning true
or false
.
我认为如果您编写success
函数以加载适当的页面而不是返回true
或false
.
For example instead of returning true
you could do:
例如,true
您可以执行以下操作而不是返回:
window.location="appropriate page";
That way when the success function is called the page gets redirected.
这样,当调用成功函数时,页面会被重定向。
回答by Taohidul Islam
In modern JS you can simply use async
/await
, like:
在现代 JS 中,您可以简单地使用async
/ await
,例如:
async function upload() {
return new Promise((resolve, reject) => {
$.ajax({
url: $(this).attr('href'),
type: 'GET',
timeout: 30000,
success: (response) => {
resolve(response);
},
error: (response) => {
reject(response);
}
})
})
}
Then call it in an async
function like:
然后在一个async
函数中调用它,如:
let response = await upload();
回答by Frank Hoffman
Since I don't see it mentioned here I thought I'd also point out that the jQuery whenstatement can be very useful for this purpose.
因为我没有看到这里提到它,所以我想我还要指出 jQuery when语句对于这个目的非常有用。
Their example looks like this:
他们的例子是这样的:
$.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR ) {
alert( jqXHR.status ); // Alerts 200
});
The "then" part won't execute until the "when" part finishes.
“then”部分在“when”部分完成之前不会执行。