[英]jQuery ajax beforeSend
I have a simple AJAX call that is executing a function on the beforeSend
and on complete
.我有一个简单的 AJAX 调用,它在
beforeSend
和complete
上执行一个函数。 They execute fine but the beforeSend
is "seemingly" not executed until after the success.他们执行得很好,但
beforeSend
直到成功之后才“似乎”执行。
On the beforeSend
there is a "Please wait" notification.在
beforeSend
有一个“请稍候”通知。 If I put a break after the function in the beforeSend
then it will show that notification and then hit the success.如果我在
beforeSend
的函数之后放置一个中断,那么它会显示该通知,然后成功。 Without the break point then it will sit there and think while waiting for the response and then my please wait notification will appear for a fraction of a second after the success is hit.如果没有断点,那么它会坐在那里思考,等待响应,然后我的请等待通知将在成功命中后的几分之一秒内出现。
The desired functionality is to have the notification appear as soon as the request is sent so it displays while it is waiting for the response.所需的功能是在发送请求后立即显示通知,以便在等待响应时显示。
$.ajax({
type : 'POST',
url : url,
async : false,
data : postData,
beforeSend : function (){
$.blockUI({
fadeIn : 0,
fadeOut : 0,
showOverlay : false
});
},
success : function (returnData) {
//stuff
},
error : function (xhr, textStatus, errorThrown) {
//other stuff
},
complete : function (){
$.unblockUI();
}
});
Your problem is the async:false
flag.您的问题是
async:false
标志。 Besides the fact that it is bad practice (and really only makes sense in a very limited number of cases), it actually messes with the order of execution of the rest of the code.除了这是不好的做法(实际上只在非常有限的情况下才有意义)这一事实之外,它实际上扰乱了其余代码的执行顺序。 Here is why:
原因如下:
It seems that somewhere in the blockUI
code they are setting a setTimeout
.似乎在
blockUI
代码的某个地方,他们正在设置setTimeout
。 As a result, the blockUI
code waits a very short amount of time.因此,
blockUI
代码等待的时间非常短。 Since the next instruction in the queue is the ajax()
call, the blockUI
execution gets placed right behind that.由于队列中的下一条指令是
ajax()
调用, blockUI
执行就放在它的后面。 And since you are using async:false
, it has to wait until the complete ajax
call is completed before it can be run.并且由于您使用的是
async:false
,因此它必须等到完整的ajax
调用完成后才能运行。
In detail, here is what happens:详细来说,这是发生了什么:
blockUI
blockUI
blockUI
has a setTimeout and gets executed after the timeout is done (even if the timeout length is 0, the next line, ajax()
will be run first) blockUI
有一个 setTimeout 并在超时完成后执行(即使超时长度为 0,下一行ajax()
也会先运行)ajax()
is called with async:false
, which means JS stops everything until the request returns ajax()
用async:false
调用,这意味着 JS 停止一切,直到请求返回ajax()
returns successfully and JS execution can continue ajax()
返回成功,JS 可以继续执行blockUI
code is probably over, so it will be executed next blockUI
代码里面的setTimeout大概已经结束了,接下来会执行blockUI
runs as part of success
, but in reality, it has just been queued up because of a timeoutblockUI
作为success
一部分运行,但实际上,它只是因为超时而排队If you would NOT use async:false
, the execution would go as followed:如果您不使用
async:false
,则执行将如下所示:
blockUI
blockUI
blockUI
has a setTimeout and gets executed after the timeout is done (even if the timeout length is 0, the next line, ajax()
will be run first) blockUI
有一个 setTimeout 并在超时完成后执行(即使超时长度为 0,下一行ajax()
也会先运行)ajax()
is called and sends of a request to the server. ajax()
被调用并向服务器发送请求。blockUI
code is probably over, so it will be executed next blockUI
代码里面的setTimeout大概已经结束了,接下来会执行blockUI
text shows up blockUI
文本出现success
and complete
callbacks are executedsuccess
并执行complete
回调Here are some jsFiddle examples to demonstrate the problem:以下是一些 jsFiddle 示例来演示该问题:
Example 1 : This is the situation you are experiencing.示例 1 :这就是您遇到的情况。 The
blockUI
text doesn't show until after the ajax
call executes. blockUI
文本直到ajax
调用执行后才会显示。
Example 2 : This is the exact same situation as yours, but with an alert
before the ajax
call.示例 2 :这与您的情况完全相同,但在
ajax
调用之前有一个alert
。 Because there is an alert
, the timeout inside blockUI
places the appearance of the blockUI
text after the alert
instead of after the ajax
.因为有一个
alert
, blockUI
内的超时将blockUI
文本的外观blockUI
alert
而不是ajax
。
Example 3 : This is how it is supposed to work without async:false
示例 3 :这就是没有
async:false
它应该如何工作
This is most probably because of async : false
.这很可能是因为
async : false
。 As your call is synchronous, after your call to the $.ajax()
function begins, nothing happens until the response is received, and the next thing as far as your code goes will be the success
handler由于您的调用是同步的,因此在开始调用
$.ajax()
函数后,在收到响应之前不会发生任何事情,并且就您的代码而言,接下来的事情将是success
处理程序
To make it work, You can do something like this为了使它工作,你可以做这样的事情
$.blockUI({
fadeIn : 0,
fadeOut : 0,
showOverlay : false
});
// and here goes your synchronous ajax call
$.ajax({
type : 'POST',
url : url,
async : false,
data : postData,
success : function (returnData) {
//stuff
},
error : function (xhr, textStatus, errorThrown) {
//other stuff
},
complete : function (){
$.unblockUI();
}
});
$.blockUI({
fadeIn : 0,
fadeOut : 0,
showOverlay : false
});
setTimeout(function() {
$.ajax({
type : 'POST',
url : url,
async : false,
data : postData,
success : function (returnData) {
//stuff
},
error : function (xhr, textStatus, errorThrown) {
//other stuff
}
});
},100);
$.unblockUI();
http://bugs.jquery.com/ticket/7464 http://bugs.jquery.com/ticket/7464
Another approach could be overload $.ajax function另一种方法可能是重载 $.ajax 函数
$.orig_ajax = $.ajax;
$.ajax = function() {
var settings = {async: true};
if (2 == arguments.length && 'string' == typeof arguments[0] && 'object' == typeof arguments[1])
settings = arguments[1];
else if (arguments.length && 'object' == typeof arguments[0])
settings = arguments[0];
if (!settings.async && 'function' == typeof settings.beforeSend) {
var args = arguments;
settings.beforeSend();
var dfd = $.Deferred();
setTimeout(function() {
$.orig_ajax.apply($, args).then(dfd.resolve)
.fail(dfd.reject);
} ,100);
return dfd.promise();
} else
return $.orig_ajax.apply($, arguments);
};
not perfect (because of different deferred object), but may be helpful..不完美(因为不同的延迟对象),但可能会有所帮助..
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.