【问题标题】:Ajax call with nested ajax calls in for each带有嵌套 ajax 调用的 Ajax 调用
【发布时间】:2014-04-09 10:31:13
【问题描述】:

我遇到了以下问题。

我有以下嵌套/foreach 循环 ajax 调用结构:

var children = [];
$.fn.ajaxHelper.loadAjax({
    url: someUrlReturningJsonOfChildren,
    cache: true,
    callback: function(options) {
        var json = options.json;
        $.each(json, function (i) {
            // get the details of this child
            $.fn.ajaxHelper.loadAjax({
                url: urlForDetailsUsingId,
                cache: true,
                callback: function(options) {
                    var json = options.json;
                    children[i] = json;   
                }
            });
        }
    }
});
// want to do something with (newly filled) children here

正如您可以想象的那样,我遇到了 ajax 调用是异步的(呃)的麻烦,但我只想在所有 ajax 调用都完成后才对子数组做一些事情。否则我显然在处理一个不完整的数组。

我一直在研究一些 jQuery 解决方案,例如 Deferred 对象(使用 $.when().then() 等),但只有在我没有 foreach 循环的情况下才能解决问题(至于我知道)。

此外,遗憾的是,由于对 API 的特定要求,更改 REST API(ajax 调用所在的位置)不是一种选择。

好的,事不宜迟:你们中的任何一个天才可以帮助我吗? :-)

【问题讨论】:

  • 使用$.when 可以解决问题。你必须创建一个 promise 数组并使用 .apply 调用 $.when。这已经在这里讨论过几次了。
  • @FelixKling - 你是对的,这是重复的;此外,我更喜欢你的回答,而不是我的(下)。
  • 我同意@FelixKling。我打算结束这个问题(因为重复和该问题的答案)。虽然讨厌放弃讨论,但也不能真正接受答案(因为我(不幸)重复的问题中有更好的答案。有人对可能的解决方案有想法吗?

标签: javascript jquery ajax knockout.js


【解决方案1】:

当上一个查询成功完成时,您必须运行 ajax 查询(在 jQuery onSuccess 回调中)

【讨论】:

    【解决方案2】:

    ajax 默认是异步的,但是你可以关闭它。这里是关于如何做到这一点的 API

    https://api.jquery.com/jQuery.ajax/

    这里有个小坑

    $.ajax({
       url: my_url.php,
       type: "POST",
       async: false,
       dataType: 'json'
    });
    

    或者只是在成功函数中进行下一次 ajax 调用(推荐

    function testAjax(handleData) {
       $.ajax({
       url:"getvalue.php",  
    
       success:function(data) {
          //next ajax call here
       }
    
     });
    }
    

    【讨论】:

    • 如果你喜欢这个答案,请点赞:)
    • 我猜 OP 可能遇到的问题是如何将循环转换为这种模式。此外,这将使 Ajax 调用是顺序的,而不是并行的,因此可能需要更长的时间才能收到所有结果。
    【解决方案3】:

    我遇到了一个微笑问题...下面是我的解决方案的简化版本。

    第一步:声明全局变量。

    var results1,
        results2,
        [resultsN];
    

    第二步:制作一个函数,接受每个 AJAX 调用的结果作为参数。

    function foo(results1, results2, [resultsN]) {
        if (results1, results2, [resultsN]) {
            //... do whatever you want with all of your results
        }
    }
    

    第三步:调用所有AJAX函数,将结果设置为全局变量,并为每个函数调用foo

    function ajax() {
        //AJAX call 1
        $.ajax({
            type: 'POST',
            url: //URL,
            success: function (data, textStatus, jqXHR) {
                results1 = data;
            },
            dataType: 'json',
            complete: function () {
                foo(results1, results2);
            }
        });
    
        //AJAX call 2
        $.ajax({
            type: 'POST',
            url: //URL,
            success: function (data, textStatus, jqXHR) {
                results2 = data;
            },
            dataType: 'json',
            complete: function () {
                foo(results1, results2);
            }
        });
    };
    

    此方法的优点是运行速度与最长的 AJAX 调用一样快。如果您只是将 AJAX 查询嵌套在 complete 事件中,那么您将不得不等待每个 AJAX 调用完成,然后再转到下一个...

    【讨论】:

    • 我建议不要使用 n 个全局变量,而是使用数组。
    • @FelixKling - 我同意。我使用面向对象的 JavaScript 并将这个变量设置为一个属性。您可以使用数组来减少全局变量的数量,但我不想在此示例中弄混水。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    相关资源
    最近更新 更多