2013-11-03 50 views
0

我有一組嵌套的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(),但我發現所有的樣本似乎都應該在第一次迭代後觸發...

(這些函數是故意分開的,因爲有時候有理由只使用一個或只使用另一個)。

提前致謝!

+0

更正了您的代碼,而不是回答。 data:'q = cat',應該是data:'q ='+ cat和data:'q = subcat',應該是data:'q ='+ subcat,因爲你傳遞的是函數的值。 –

+0

嗯,你說的對,在真實的代碼中是正確的 - 我在簡化它時錯誤地轉錄了它。 (它也有更多的論據,等等) –

回答

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) 
    }); 
} 
+0

這是非常明顯的。只要在通過觀看計數完成之前不要致電回撥,杜。我認爲睡眠不足。非常感謝。 –

0

首先,您應該在服務器端組織您的數據庫查詢,以便它返回一個單一的多重結果。而不是多次打電話。

除此之外,假設您不知道在您的類別調用返回之前要調用多少個子類別,最好的方法是創建一個全局變量,每次調用時都會計數,然後每次回調收到結果時都會倒計時。每當回調觸發,倒計時,新計數爲零時,請進行更新。

+0

有效,但這仍然是一個有很多移動目標的項目 - 足以讓我暫時拋棄這些東西,因爲一半的時間努力讓它無用。這些優化正在等待功能穩定,但感謝:-) –