2009-11-17 107 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