【问题标题】:Best approach for dependent ajax calls in jQueryjQuery中依赖ajax调用的最佳方法
【发布时间】:2015-06-29 12:18:00
【问题描述】:

我有需要进行 5 次 ajax 调用的情况。第二次ajax调用将在第一次调用返回响应后进行,第三次调用在第二次调用完成时进行,第四次和第五次调用也是如此。

我知道有 2 种方法,我可以在前一次调用成功时嵌套 ajax 调用,或者在第一次调用之前将异步设为 false,在最后一次调用后设为 true。任何人都可以建议哪个是以及为什么它是完成我的任务的更好方法,或者有更好的方法来做到这一点。

//First Way
$.ajax({
...
success:function(){
    $.ajax({
    ...
        success:function(){
            $.ajax({
            ...
                success:function(){
                    $.ajax({
                    ...
                        success:function(){
                              do something      
                        }
                    });
                }
            });
        }
    });
}
});

//second way 
$.ajaxSetup({
    async: false
});
$.ajax({
});
$.ajax({
});
$.ajax({
});
$.ajax({
});
$.ajax({
});
$.ajaxSetup({
    async: true
});

【问题讨论】:

  • 每次请求后执行的逻辑是什么?每个的逻辑是否相似,或者您只需要确保调用按此顺序发生?另请注意,async: false 非常糟糕。几乎是eval 级别的差;)
  • 请告诉我们导致您这样做的原因和情况。
  • @RoryMcCrossan 我的要求是调用一个接一个的顺序
  • 在这种情况下,您需要像第一个示例一样链接您的调用。
  • 这里需要 Promise。要了解更多信息:javascriptplayground.com/blog/2015/02/promises 或者 jQuery 可以帮助您 api.jquery.com/category/deferred-object

标签: javascript jquery ajax


【解决方案1】:

任何人都可以建议哪个是以及为什么它是完成我的任务的更好方法...

使用async: false 将使调用同步,这会在调用运行时锁定浏览器的用户界面。调用运行时最好让 UI 保持响应。

所以最好保持异步调用;有几种方法可以做到这一点:

正如您所演示的,正在使用 success 处理程序:

$.ajax({
    /*...*/,
    success: function() {
        $.ajax({
            /*...*/,
            success: function() {
                $.ajax({
                    /*...*/,
                    success: function() {
                        $.ajax({
                            /*...*/,
                            success: function() {
                                $.ajax({
                                    /*...*/
                                });
                            }
                        });
                    }
                });
            }
        });
    }
});

(我假设您已经注册了一个全局 ajax 错误处理程序,或者您在上面的/*...*/ 中有一个。)

这里使用了一个承诺链,这非常相似:

$.ajax({/*...*/})
    .done(function() {
        $.ajax({/*...*/})
            .done(function() {
                $.ajax({/*...*/})
                    .done(function() {
                        $.ajax({/*...*/})
                            .done(function() {
                                $.ajax({/*...*/});
                            });
                    });
            });
    });

或者你可以使用函数循环,像这样:

(function() {
    var calls = [
        function() { $.ajax({/*...*/, success: next)},
        function() { $.ajax({/*...*/, success: next)},
        function() { $.ajax({/*...*/, success: next)},
        function() { $.ajax({/*...*/, success: next)},
        function() { $.ajax({/*...*/, success: next)}
    ];
    var index = 0;
    next();

    function next() {
        if (index < calls.length) {
            // Do the next, increment the call index
            calls[index++]();
        }
    }
})();

【讨论】:

  • 我们能否检查每个 AJAx 调用的任何输出,并相应地调用或避免进一步调用所有 AJAX 事件,例如返回 false 或 else?
  • @Vikrant:如果您在谈论函数循环,那么您没有理由不能在任何给定的 ajax 调用上设置一个可以由 successfail 回调设置的标志尽早停止“循环”。
  • 我们可以做类似function() { $.ajax({/*...*/, success: function (){ ret = false;}, complete: next})} if(ret == true) function() { $.ajax({/*...*/, complete: next})}, ...的事情吗?
  • @Vikrant:使用函数循环会干净得多。然后,您只需在 index 旁边声明一个变量标志,并让 next 检查标志。
  • 您是否将其包装在更紧密的位置以便清理调用数组?我是否需要担心清理变量或可能存在内存问题?
猜你喜欢
  • 2012-10-09
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 2021-06-02
  • 2013-03-08
相关资源
最近更新 更多