2009-11-17 148 views
0

我需要等待for循環內的ajax響應。如果我可以,我只是做一個同步調用而不是異步調用,但我沒有這種控制級別:我使用別人的API,然後調用eBay的Javascript API。等待循環內的ajax響應

下面是我的兩個函數,實際上是對同一個閉包/對象的方法,categoryStack和categoryMap在每個範圍內。實質上,我試圖遞歸地建立一個地圖,但我想用堆棧進行管理,而不是真正的遞歸。

我已經嘗試了setInterval/setTimeout上的一些變化,但我總是得到兩個結果之一:循環的一次迭代或無限循環。請注意,m_eBay.getChildCategories將以下兩個函數中的第二個函數指定爲回調函數,並且我確認我已成功執行此操作。

function getChildCategories() { 
    categoryStack.push(-1); 

    while (categoryStack.length > 0) { 
     catId = categoryStack.pop(); 

     m_eBay.getChildCategories({ 
      'success':getChildCategoriesSuccess, 
      'failure':getChildCategoriesFailure}, 
      {'siteid':0, 'CategoryID':catId, 'IncludeSelector':'ChildCategories'} 
     ); 

     /* 
      use response from getChildCategoriesSuccess to reset categoryStack 
     */ 
    } 
} 

    function getChildCategoriesSuccess(data){ 
     if (data.categoryCount > 0) { 
      var categoryObjs = data.categoryArray.category; 
      for (var i=0, n=categoryObjs.length; i<n; i++) { 
       var catObj = categoryObjs[i]; 
       if (catObj.categoryID != -1) { //skip root 
        categoryStack.push(catObj.categoryID); 
        categoryMap[catObj.categoryName] = catObj.categoryID; 
       } 
      } 
     } 
    } 
+0

我沒有看到反正這樣做沒有遞歸。在本質上,遞歸成爲循環。 – Zoidberg

+0

據我所知,使用堆棧總是替代遞歸。儘管遞歸可能會在沒有任何干預的情況下構建整個地圖,但我仍然想知道遞歸何時完成。所以我實際上認爲這是通過遞歸還是通過管理堆棧來實現是一個有爭議的問題,我認爲,如果你不需要遞歸,就不要使用它。 –

回答

0

使用AJAX的異步你需要做的是這樣的:

function getChildCategories(onload) { 
    var categoryStack = [-1]; 
    function doNextOrFinish() { 
     if (categoryStack.length) { 
      m_eBay.getChildCategories({ 
       'success': function(data) { 
        if (data.categoryCount > 0) { 
         var categoryObjs = data.categoryArray.category; 
         for (var i=0, n=categoryObjs.length; i<n; i++) { 
          var catObj = categoryObjs[i]; 
          if (catObj.categoryID != -1) { //skip root 
           categoryStack.push(catObj.categoryID); 
           categoryMap[catObj.categoryName] = catObj.categoryID; 
          } 
         } 
        } 
        doNextOrFinish(); 
       }, 
       'failure':getChildCategoriesFailure}, 
       {'siteid':0, 'CategoryID':categoryStack.shift(), 'IncludeSelector':'ChildCategories'} 
      ); 
     } else { 
      if (onload) onload(); 
     } 
    } 
    doNextOrFinish(); 
} 

仍然使用遞歸雖然。

此問題的另一個解決方案是使用Arrows