Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/89.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery-ajax发送前_Javascript_Jquery_Jquery Blockui - Fatal编程技术网

Javascript jQuery-ajax发送前

Javascript jQuery-ajax发送前,javascript,jquery,jquery-blockui,Javascript,Jquery,Jquery Blockui,我有一个简单的AJAX调用,它在beforeSend和complete上执行一个函数。它们执行得很好,但发送前的似乎在成功后才执行 在发送前的上有一个“请稍候”通知。如果我在发送前的beforeSend中的函数后加了一个中断符,那么它将显示该通知,然后点击成功按钮。如果没有断点,它将在等待响应时坐在那里思考,然后我的请等待通知将在成功点击后出现一小部分秒 所需的功能是在发送请求时立即显示通知,以便在等待响应时显示通知 $.ajax({ type : 'PO

我有一个简单的AJAX调用,它在
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执行将一直执行到AJAX
    success
    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请求之前和之后,但是功能没有改变