所有请求完成后,使用递归函数依次执行多个ajax请求并执行回调函数

时间:2014-12-16 07:46:22

标签: javascript ajax recursion

我有逗号分隔的名字列表。我想要的是我想为序列中的所有名称调用服务器请求并将结果存储在数组中。当我在字符串中有多个名字时,我尝试了它并且它正在工作。

请参阅Here - 当我知道姓名数量

时,此功能正常

现在我想要的是我想把这段代码变成通用的。如果我在该字符串中添加一个名称,它应该自动处理而不添加任何ajax请求的代码。

请参阅Here - 这是我尝试过的。它没有按预期工作。

shoppingList = shoppingList.split(",");
var result = [];

function fetchData(shoppingItem)
{
    var s1 = $.ajax('/items/'+shoppingItem);
    s1.then(function(res) {
        result.push(new Item(res.label,res.price));
        console.log("works fine");
    });
    if(shoppingList.length == 0)
    {
        completeCallback(result);
    }
    else
    {
        fetchData(shoppingList.splice(0,1)[0]);
    }
}

fetchData(shoppingList.splice(0,1)[0]);

问题

我没有得到如何检测所有promise对象已被解析,以便我可以调用回调函数。

3 个答案:

答案 0 :(得分:1)

要按顺序发出ajax请求,必须将递归调用放在回调中:

function fetchList(shoppingList, completeCallback) {
    var result = [];
    function fetchData() {
        if (shoppingList.length == 0) {
            completeCallback(result);
        } else {
            $.ajax('/items/'+shoppingList.shift()).then(function(res) {
                result.push(new Item(res.label,res.price));
                console.log("works fine");
                fetchData();
//              ^^^^^^^^^^^
            });
        }
    }
    fetchData();
}

或者你实际上使用了promises并且做了

function fetchList(shoppingList) {
    return shoppingList.reduce(function(resultPromise, shoppingItem) {
        return resultPromise.then(function(result) {
            return $.ajax('/items/'+shoppingItem).then(function(res) {
                result.push(new Item(res.label,res.price));
                return result;
            });
        });
    }, $.when([]));
}

updated jsfiddle


请注意,任务的要求中没有任何关于按顺序执行ajax请求的内容。您也可以让它们并行运行wait for all of them to finish

function fetchList(shoppingList) {
    $.when.apply($, shoppingList.map(function(shoppingItem) {
        return $.ajax('/items/'+shoppingItem).then(function(res) {
            return new Item(res.label,res.price);
        });
    })).then(function() {
        return Array.prototype.slice.call(arguments);
    })
}

updated jsfiddle

答案 1 :(得分:0)

// global:
var pendingRequests = 0;

// after each ajax request:
pendingRequests++;

// inside the callback:
if (--pendingRequest == 0) {
    // all requests have completed
}

答案 2 :(得分:0)

我已将您的代码修改为最小值以使其正常工作 - Click here

请注意您的上一个断言将失败,因为项目承诺未以线性方式解决。因此,项目的顺序将会改变。