2009-11-17 3 views
0

Мне нужно дождаться ответа ajax внутри цикла for. Если бы я мог просто сделать синхронный вызов вместо асинхронного, но у меня нет такого уровня контроля: я использую чужой API, который, в свою очередь, вызывает Javascript API eBay.ожидание ответа ajax внутри цикла

Ниже приведены мои две функции, на самом деле методы на одном и том же закрытии/объекте, с категориямиStack и 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.

Смежные вопросы