2009-11-17 2 views
0

Je dois attendre une réponse ajax à l'intérieur d'une boucle for. Si je pouvais simplement faire un appel synchrone au lieu d'asynchrone, mais je n'ai pas ce niveau de contrôle: j'utilise l'API de quelqu'un d'autre qui à son tour appelle l'API Javascript d'eBay. Ci-dessous sont mes deux fonctions, en fait des méthodes sur la même fermeture/objet, avec categoryStack et categoryMap dans la portée de chacun. Essentiellement, j'essaye de construire récursivement une carte, bien que je veuille utiliser une pile pour la gestion, plutôt que la vraie récursivité.attendre une réponse ajax à l'intérieur d'une boucle

J'ai essayé quelques variantes de setInterval/setTimeout mais j'ai toujours deux résultats: une itération de la boucle, ou une boucle sans fin. Notez que m_eBay.getChildCategories spécifie la deuxième des deux fonctions ci-dessous comme rappel, et j'ai confirmé que j'y arrive avec succès.

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

Je ne vois pas de toute façon de le faire sans récursion. En effet, la récursivité devient la boucle. – Zoidberg

+0

Pour autant que je sache, l'utilisation d'une pile est toujours une alternative à la récursivité. Bien que la récursivité puisse construire toute la carte sans aucune intervention, je voudrais quand même savoir quand la récursion est terminée. Donc je pense réellement si cela est implémenté en utilisant la récursivité, ou en gérant une pile, est un point discutable, et je suis d'avis, si vous n'avez pas besoin de récursion, ne l'utilisez pas. –

Répondre

0

utilisant Ajax asynchrone vous devez faire quelque chose comme:

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(); 
} 

utilise encore récursion bien.

Une autre solution à ce problème consiste à utiliser Arrows.

Questions connexes