从循环嵌套的AJAX查询返回数据

时间:2013-11-03 06:28:23

标签: javascript jquery ajax

我有一组嵌套的ajax调用,类似于:

function getSubcategories(cat,callback) {
  $.ajax({
    url:'myurl.php',
    data:'q='+cat,
    dataType='json',
    success:function(result){ callback(result) }
  });
}

function getSubcatElements(subcat,callback) {
  $.ajax({
    url:'myurl2.php',
    data:'q='+subcat,
    dataType='json',
    success:function(result){ callback(result) }
  });
}  

function organizeData(cat,callback) {
getSubcategories(cat,function(res){
  totals=0;
  list=new Array;
  $.each(res['subcat'],function(key,val){
    getSubcatElements(val,function(items){
      $.each(items['collection'],function(key2,val2) {
        list.push(val2['descriptor']);
      });
      totals+=items['count'];
      // If I shove "totals" and "list" into an object here to callback, obviously gets called many times
    }
    // If I return an object here, it doesn't actually have counts from the asynchronous call above
  }

function doStuff(cat) {
  organizeData(cat,function() {
    //stuff
  });

所以我正在运行一个循环异步查询,它是另一个异步查询的子代,我希望子循环的最终结果不是“懒惰”。现在我只是返回更新的结果,所以数字改变了几次,但我想一下子做。

似乎显而易见的地方是将结果存储在异步中并在$.each()之后返回它,但JavaScript是疯狂的并且嘲笑明显的事情。我觉得这应该涉及$.Deferred(),但我发现的样本似乎都应该在第一次迭代后触发......

(这些功能是故意分开的,因为有时候只使用一个或仅使用另一个)。

提前致谢!

2 个答案:

答案 0 :(得分:0)

首先,您应该在服务器端组织数据库查询,以便返回单个,多重复用的结果。而不是多次调用它。

除此之外,假设您在类别调用返回之前不知道要调用多少个子类别,最好的办法是创建一个全局变量,每次调用时都会计入,并且然后每次回调收到结果时倒计时。每当回调触发,倒计时,新计数为零时,请进行更新。

答案 1 :(得分:0)

现在,你的方法很好。我想在您的代码中添加以下更改

function organizeData(cat, callback) {
    getSubcategories(cat, function(res) {
        totals = 0;
        list = new Array();
        totalSubCatItem = res['subcat'].length;
        currentSubCatItem = 0;
        $.each(res['subcat'], function(key, val) {
            getSubcatElements(val, function(items) {
                $.each(items['collection'], function(key2, val2) {
                    list.push(val2['descriptor']);
                });
                totals += items['count'];
                // If I shove "totals" and "list" into an object here to callback, obviously gets called many times
                // Here the solution
                currentSubCatItem++;
                if(currentSubCatItem === totalSubCatItem){
                    callback(/** pass argument here **/)
                }           

            });
            // If I return an object here, it doesn't actually have counts from the asynchronous call above
        });
    })
}

function doStuff(cat) {
    organizeData(cat, function( result) {
        //stuff
        console.log(result)
    });
}
相关问题