ждать ответа ajax внутри цикла - PullRequest
0 голосов
/ 17 ноября 2009

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

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

1 Ответ

0 голосов
/ 27 ноября 2009

Используя асинхронный 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();
}

Тем не менее все еще использует рекурсию.

Другим решением этой проблемы является использование Стрелки .

...