0

我有一组嵌套的 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()在 . 我觉得这应该涉及$.Deferred(),但我发现的所有样本似乎都应该在第一次迭代后触发......

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

提前致谢!

4

2 回答 2

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)
    });
}
于 2013-11-03T06:53:51.113 回答
0

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

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

于 2013-11-03T06:32:55.597 回答