【问题标题】:Wait for AJAX Call (POST) to Finish等待 AJAX 调用 (POST) 完成
【发布时间】:2010-09-14 21:22:24
【问题描述】:

我正在使用 jQuery UI 选项卡,其中每个选项卡上都有不同的表单。用户输入各种数据后,提交整组选项卡,以便每个选项卡异步发布到服务器。这很好用,我这里没有问题。

但是,我遇到的问题是,我发布的最后一个表单必须在所有其他帖子完成之后发生。大致思路是这样的:

postForm(0, "#Form1");
postForm(1, "#Form2");
postForm(2, "#Form3");
postForm(3, "#Form4");
$.post('Project/SaveProject', function (data) {
    $('<div class="save-alert">The current project has been saved.</div>')
    .insertAfter($('#tabs'))
    .fadeIn('slow')
    .animate({ opacity: 1.0 }, 3000)
    .fadeOut('slow', function () {
        $(this).remove();
    });
});

postForm 函数进行一些处理,然后进行 AJAX $.post 调用。此处执行的最后一个 $.post(到“Project/SaveProject”)必须等到其他帖子完成。这样做的最佳方法是什么?

【问题讨论】:

    标签: jquery ajax post


    【解决方案1】:

    您可以只使用在所有其他 AJAX POST 完成时触发的 .ajaxStop() 事件,假设您没有执行其他 AJAX 工作,如下所示:

    postForm(0, "#Form1");
    postForm(1, "#Form2");
    postForm(2, "#Form3");
    postForm(3, "#Form4");
    $(document).ajaxStop(function() {
      $.post('Project/SaveProject', function (data) {
        $('<div class="save-alert">The current project has been saved.</div>')
        .insertAfter($('#tabs'))
        .fadeIn('slow')
        .animate({ opacity: 1.0 }, 3000)
        .fadeOut('slow', function () {
          $(this).remove();
        });
      });
      $(this).unbind('ajaxStop');
    });
    

    .ajaxStop()所有 正在运行的 AJAX 请求完成时触发,因此它只会在 所有 这些 POST 都返回时触发,jQuery 在内部保持计数( $.active, $.ajax.active 在 jQuery 1.5 中)来确定有多少并发 AJAX 请求未完成......当它回到 0 时触发此事件。

    这种方法让您可以同时提交其他表单,然后尽快完成最终表单。

    【讨论】:

    • 感谢您在 jQuery 1.5 中提及 $.ajax.active
    【解决方案2】:

    你总是可以使用类似的东西使所有帖子同步

    
    $.ajax({
       type: "POST",     
       async: false,
       url: "",
       ...
    

    当然它不会那么快,但如果 $(document).ajaxStop 不是一个选项,它确实可以解决您的问题

    【讨论】:

    • 这实际上不再起作用,它返回以下消息:“主线程上的同步 XMLHttpRequest 已被弃用,因为它对最终用户的体验产生不利影响。”
    【解决方案3】:

    回调:

    定义 postForm 以进行回调:

    function postForm(ind, id, callback)
    {
      // ...
      $.post(url, function()
      {
        // ...
        callback();
      });
    }
    

    然后执行以下操作。您可以使用递归以较少硬编码的方式编写它,如果有更多的表单,这可能特别有用。

    postForm(0, "#Form1", function()
    {
        postForm(1, "#Form2", function()
        { 
            postForm(2, "#Form3", function()
            {
                postForm(3, "#Form4", function()
                {
                    $.post('Project/SaveProject', function (data) {
                        $('<div class="save-alert">The current project has been saved.</div>')
                            .insertAfter($('#tabs'))
                            .fadeIn('slow')
                            .animate({ opacity: 1.0 }, 3000)
                            .fadeOut('slow', function () {
                                $(this).remove();
                            });
                    });
                });
            });
        });
    });
    

    【讨论】:

    • 感谢您的回复。我最初考虑过这个,但后来觉得它有点太麻烦了。 (+1)
    【解决方案4】:

    ajaxStop 的问题是每次完成任何 ajax 时都会触发。另一种方法是实现您自己的方法堆栈,如下所示:

    var stack = []
    postForm(var1, var2){
        stack.push(1);
        //Do postForm stuff
        stack.pop();
        if (stack == undefined){
            //Call the last post method
        }
    }
    postForm(0, "#Form1");
    postForm(1, "#Form2");
    postForm(2, "#Form3");
    postForm(3, "#Form4");
    $.post('Project/SaveProject', function (data) {
        $('<div class="save-alert">The current project has been saved.</div>')
        .insertAfter($('#tabs'))
        .fadeIn('slow')
        .animate({ opacity: 1.0 }, 3000)
        .fadeOut('slow', function () {
            $(this).remove();
        });
    });
    

    【讨论】:

    • ajaxStop() 只会在 all AJAX 请求完成时触发,并且我在第一次运行时将其解除绑定,您能否详细说明这可能是一个问题?您的示例也不起作用,因为 stack 将是一个空数组,而不是 undefined :)
    • 没有看到底部的解除绑定,对此表示歉意。根据应用程序的不同,可能会有很多 ajax 调用飞来飞去,在需要绝对控制的情况下,我会为我的工作流程创建自己的调用堆栈。当然,您的代码也可以工作(至少如果应用程序早期没有任何 ajax 调用,您必须在 postForm 方法中定义处理程序)
    • 在这批请求被触发之前,我不会绑定处理程序:)
    猜你喜欢
    • 1970-01-01
    • 2011-09-08
    • 2012-05-04
    • 2017-08-18
    • 1970-01-01
    • 2018-06-09
    • 2017-05-20
    • 2011-09-06
    • 2013-10-14
    相关资源
    最近更新 更多