Javascript jQuery-ajax发送前
我有一个简单的AJAX调用,它在Javascript jQuery-ajax发送前,javascript,jquery,jquery-blockui,Javascript,Jquery,Jquery Blockui,我有一个简单的AJAX调用,它在beforeSend和complete上执行一个函数。它们执行得很好,但发送前的似乎在成功后才执行 在发送前的上有一个“请稍候”通知。如果我在发送前的beforeSend中的函数后加了一个中断符,那么它将显示该通知,然后点击成功按钮。如果没有断点,它将在等待响应时坐在那里思考,然后我的请等待通知将在成功点击后出现一小部分秒 所需的功能是在发送请求时立即显示通知,以便在等待响应时显示通知 $.ajax({ type : 'PO
beforeSend
和complete
上执行一个函数。它们执行得很好,但发送前的似乎在成功后才执行
在发送前的上有一个“请稍候”通知。如果我在发送前的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();
}
});
这很可能是因为async:false
。由于您的呼叫是同步的,
调用$.ajax()
函数开始后,在收到响应之前不会发生任何事情,下一步代码将是成功
处理程序
为了让它发挥作用,你可以这样做
$.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();
}
});
您的问题是async:false
标志。除此之外,这是一种糟糕的做法(并且只在非常有限的情况下才有意义),它实际上扰乱了代码其余部分的执行顺序。原因如下:
似乎在块ui
代码中的某个地方,他们正在设置setTimeout
。因此,blockUI
代码等待的时间非常短。由于队列中的下一条指令是ajax()
调用,因此blockUI
执行被放置在它的后面。由于您使用的是async:false
,因此必须等到完成ajax
调用后才能运行
具体来说,以下是发生的情况:
- 您可以调用
blockUI
blockUI
有一个setTimeout,并在超时完成后执行(即使超时长度为0,下一行ajax()
也将首先运行)
ajax()
是用async:false
调用的,这意味着JS会停止所有操作,直到请求返回为止
ajax()
成功返回,JS执行可以继续
blockUI
code中的setTimeout可能已结束,因此将在下一步执行
- 它看起来像是作为
success
的一部分运行的blockUI
,但实际上,它只是因为超时而排队
如果不使用async:false
,执行过程如下:
- 您可以调用
blockUI
blockUI
有一个setTimeout,并在超时完成后执行(即使超时长度为0,下一行ajax()
也将首先运行)
- 调用ajax()
,并向服务器发送请求
当它连接到服务器时,正常的JS执行将继续
blockUI
code中的setTimeout可能已结束,因此将在下一步执行
此时将显示blockUI
文本
除非某个地方有更多的JS代码,否则JS执行将一直执行到AJAXsuccess
和complete
回调被执行为止
下面是一些JSFIDLE示例来演示这个问题:
:这就是您正在经历的情况。在执行ajax
调用之前,blockUI
文本不会显示
:这与您的情况完全相同,但在调用ajax
之前会发出警报。由于存在警报
,因此块UI
中的超时将块UI
文本的外观放置在警报
之后,而不是ajax
之后
:这就是它在没有async:false时的工作方式
$.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();
另一种方法是重载$.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);
};
不完美(因为不同的延迟对象),但可能会有所帮助。旁注:为什么async=false
?它正在更新页面上常用的UI。我不希望用户能够在执行这些操作时使用这些操作。beforeSend
与async:false
组合使用没有任何意义。如果你想保持异步:false
,你可以在ajax(…)
之前添加blockUI
调用,因为代码无论如何都是同步执行的。我删除了beforeSend并将blockUI放在请求之前,但是功能没有改变。你说“功能没有改变”是什么意思?你是说blockUI
调用在处理程序成功后仍在执行吗?我同意你的推理。。。我想补充一点,从技术上讲,您甚至不需要complete
回调。您可以在ajax()
部分之后添加$.unbui()
,因为它是异步的。我删除了beforeSend并完成了它,并将逻辑放在了.ajax请求之前和之后,但是功能没有改变