jquery ajax beforesend
我有一个简单的ajax调用,它在beforeSend和on complete上执行一个函数。 它们执行得很好但是beforeSend“看似”在成功之后才会被执行。 在发送之前有一个“请稍候”通知。 如果我在beforeSend中的函数之后放了一个rest,那么它将显示该通知然后点击成功。 没有断点,那么它会坐在那里等待响应时思考,然后我的请等待通知将在成功命中后出现一小段时间。 所需的function是在请求发送后立即显示通知,以便在等待响应时显示。
$.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
标志。 除了它是不好的做法(并且在非常有限的情况下才真正有意义),它实际上与其余代码的执行顺序混淆。 原因如下:
似乎在blockUI
代码中的某个地方,他们正在设置setTimeout
。 结果, blockUI
代码等待很短的时间。 由于队列中的下一条指令是ajax()
调用,因此blockUI
执行位于其后面。 由于您使用的是async:false
,因此必须等到完成ajax
调用完成才能运行。
详细而言,这是发生的事情:
- 你调用
blockUI
-
blockUI
有一个setTimeout并在超时完成后执行(即使超时长度为0,下一行,ajax()
将首先运行) - 使用
async:false
调用ajax()
,这意味着JS会在请求返回之前停止所有操作 -
ajax()
成功返回,JS执行可以继续 -
blockUI
代码中的setTimeout可能已经结束,因此接下来会执行 - 看起来像
blockUI
作为success
一部分运行,但实际上,由于超时,它刚刚排队
如果你不使用async:false
,执行将如下所示:
- 你调用
blockUI
-
blockUI
有一个setTimeout并在超时完成后执行(即使超时长度为0,下一行,ajax()
将首先运行) - 调用
ajax()
并将请求发送到服务器。 - 当它连接到服务器时,正常的JS执行继续
-
blockUI
代码中的setTimeout可能已经结束,因此接下来会执行 -
blockUI
文本显示出来 - 除非在某处有更多的JS代码,否则JS执行完成直到AJAX
success
并执行complete
回调
以下是一些用于演示此问题的jsFiddle示例:
示例1 :这是您遇到的情况。 在执行ajax
调用之后才会显示blockUI
文本。
示例2 :这与您的情况完全相同,但在ajax
调用之前有一个alert
。 因为有alert
,所以blockUI
内的超时blockUI
alert
blockUI
的blockUI
文本的外观放在ajax
。
示例3 :这是没有async:false
假设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();
另一种方法可能是重载$ .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); };
不完美(因为不同的延期对象),但可能会有所帮助..