jQuery的AJAX beforesend(jquery ajax beforesend)

2019-08-31 08:42发布

我有一个执行的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();
            }
        });

Answer 1:

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



Answer 2:

这是最有可能是因为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();
            }
     });


Answer 3:

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



Answer 4:

另一种方法可能是超载$就功能

$.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);
};

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



文章来源: jquery ajax beforesend