等待循环内的ajax响应

时间:2009-11-17 18:17:34

标签: javascript ajax recursion loops sleep

我需要在for循环中等待ajax响应。如果我可以简单地进行同步调用而不是异步调用,但我没有那种控制级别:我正在使用其他人的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 :(得分: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