我有一个执行的beforeSend和完整的功能简单的Ajax调用。 他们执行罚款,但beforeSend是“貌似”直到成功后执行。 在发送前有一个“请等待”的通知。 如果我把一个破发的beforeSend功能后,然后它会显示该通知,然后打成功。 如果没有断点,然后它会坐在那里,想在等待响应,然后我请稍候成功命中通知后会出现一秒钟的一小部分。 所需的功能是尽快具有通知显示为被发送的请求,使其显示,而它正在等待的响应。
$.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. 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
. As a result, the blockUI
code waits a very short amount of time. Since the next instruction in the queue is the ajax()
call, the blockUI
execution gets placed right behind that. And since you are using async:false
, it has to wait until the complete ajax
call is completed before it can be run.
In detail, here is what happens:
- You call
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)
ajax()
is called with async:false
, which means JS stops everything until the request returns
ajax()
returns successfully and JS execution can continue
- the setTimeout inside
blockUI
code is probably over, so it will be executed next
- it looks like
blockUI
runs as part of success
, but in reality, it has just been queued up because of a timeout
If you would NOT use async:false
, the execution would go as followed:
- You call
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)
ajax()
is called and sends of a request to the server.
- while it is connecting to the server, normal JS execution continues
- the setTimeout inside
blockUI
code is probably over, so it will be executed next
- the
blockUI
text shows up
- unless there is more JS code somewhere, JS execution is done until the AJAX
success
and complete
callbacks are executed
Here are some jsFiddle examples to demonstrate the problem:
Example 1: This is the situation you are experiencing. The blockUI
text doesn't show until after the ajax
call executes.
Example 2: This is the exact same situation as yours, but with an alert
before the ajax
call. Because there is an alert
, the timeout inside blockUI
places the appearance of the blockUI
text after the alert
instead of after the ajax
.
Example 3: This is how it is supposed to work without async:false
这是最有可能是因为async : false
。 当您的调用是同步的,您的来电后$.ajax()
函数开始,什么都不会发生,直到接收到响应,接下来的事情,只要你的代码都将是success
处理程序
为了使它的工作,你可以做这样的事情
$.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
另一种方法可能是超载$就功能
$.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);
};
不完美(因为不同的递延对象),但可能会有所帮助..