jQuery ajax beforeSend

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16046387/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 16:15:28  来源:igfitidea点击:

jQuery ajax beforeSend

javascriptjqueryjquery-blockui

提问by user1134179

I have a simple AJAX call that is executing a function on the beforeSendand on complete. They execute fine but the beforeSendis "seemingly" not executed until after the success.

我有一个简单的 AJAX 调用,它在beforeSend和 on 上执行一个函数complete。他们执行得很好,但beforeSend“似乎”直到成功之后才执行。

On the beforeSendthere is a "Please wait" notification. If I put a break after the function in the beforeSendthen it will show that notification and then hit the success. 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.

beforeSend有一个“请稍候”通知。如果我在函数之后中断,beforeSend那么它将显示该通知,然后成功。如果没有断点,它会坐在那里思考,等待响应,然后我的请等待通知将在成功命中后的几分之一秒内出现。

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();
            }
        });

采纳答案by Steve

Your problem is the async:falseflag. 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:

你的问题是async:false国旗。除了这是不好的做法(实际上只在非常有限的情况下才有意义)这一事实之外,它实际上扰乱了其余代码的执行顺序。原因如下:

It seems that somewhere in the blockUIcode they are setting a setTimeout. As a result, the blockUIcode waits a very short amount of time. Since the next instruction in the queue is the ajax()call, the blockUIexecution gets placed right behind that. And since you are using async:false, it has to wait until the complete ajaxcall is completed before it can be run.

似乎在blockUI代码中的某个地方他们设置了一个setTimeout. 因此,blockUI代码等待的时间非常短。由于队列中的下一条指令是ajax()调用,因此blockUI执行就放在它的后面。并且由于您正在使用async:false,它必须等到完整ajax调用完成才能运行。

In detail, here is what happens:

详细来说,这是发生了什么:

  • You call blockUI
  • blockUIhas 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 blockUIcode is probably over, so it will be executed next
  • it looks like blockUIruns as part of success, but in reality, it has just been queued up because of a timeout
  • 你打电话 blockUI
  • blockUI有一个 setTimeout 并在超时完成后执行(即使超时长度为 0,下一行ajax()也会先运行)
  • ajax()调用 with async:false,这意味着 JS 停止一切,直到请求返回
  • ajax()成功返回,可以继续执行JS
  • blockUI代码里面的setTimeout可能已经结束了,所以接下来会执行
  • 看起来像是blockUI作为 的一部分运行success,但实际上,它只是因为超时而排队

If you would NOT use async:false, the execution would go as followed:

如果您不使用async:false,则执行将如下所示:

  • You call blockUI
  • blockUIhas 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 blockUIcode is probably over, so it will be executed next
  • the blockUItext shows up
  • unless there is more JS code somewhere, JS execution is done until the AJAX successand completecallbacks are executed
  • 你打电话 blockUI
  • blockUI有一个 setTimeout 并在超时完成后执行(即使超时长度为 0,下一行ajax()也会先运行)
  • ajax()被调用并向服务器发送请求。
  • 当它连接到服务器时,继续正常的 JS 执行
  • blockUI代码里面的setTimeout可能已经结束了,所以接下来会执行
  • blockUI文本显示出来
  • 除非某处有更多 JS 代码,否则 JS 执行会一直执行到 AJAXsuccesscomplete回调执行完毕

Here are some jsFiddle examples to demonstrate the problem:

以下是一些 jsFiddle 示例来演示该问题:

Example 1: This is the situation you are experiencing. The blockUItext doesn't show until after the ajaxcall executes.

示例 1:这就是您遇到的情况。该blockUI文本不显示,直到后ajax调用执行。

Example 2: This is the exact same situation as yours, but with an alertbefore the ajaxcall. Because there is an alert, the timeout inside blockUIplaces the appearance of the blockUItext after the alertinstead of after the ajax.

示例 2:这与您的情况完全相同,但alertajax调用之前有一个。因为有一个alert,里面的超时blockUIblockUI文本的外观放在了之后alert而不是之后ajax

Example 3: This is how it is supposed to work without async:false

示例 3:这就是它应该在没有的情况下工作的方式async:false

回答by Mohammad Adil

This is most probably because of 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 successhandler

这很可能是因为async : false. 由于您的调用是同步的,因此在您$.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();
            }
     });

回答by IcThuX

$.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

回答by salexch

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..

不完美(因为不同的延迟对象),但可能会有所帮助..