我需要在递归异步ajax调用之后执行一个函数。 我有:
var tree = [1, 2 ,3, 4];
recursion(0);
function recursion(i) {
$.ajax('http://example.com/' + tree[i])
.done(function (data) {
// data is array
++i;
if (tree[i] !==undefined) {
$.each(data, function () {
recursion(i);
});
}
});
}
我希望完成后的所有通话:
recursion(0).done(function () {alert('All calls are done!')});
我知道,我应该使用$ .Deferred of JQuery,但是ajax调用也会返回promise。 我试图使用$ .Deferred但我在这个地方遇到了循环问题:
$.each(data, function () {
recursion(i);
});
请帮助我。
答案 0 :(得分:1)
你需要做这样的事情:
function recursion(i) {
return $.ajax('http://example.com/' + tree[i])
.then(function (data) {
// data is array
++i;
if (tree[i] !==undefined) {
// get an array of promises
var promises = $.map(data, function () {
return recursion(i);
});
// return the `when` promise from the `then` handler
// so the outer promise is resolved when the `when` promise is
return $.when.apply($, promises);
} else {
// no subsequent calls, resolve the deferred
}
});
}
目前尚未经过测试,但它至少可以为您提供这个想法。基本上,只有在解决了所有后续调用后才解决延迟问题。
答案 1 :(得分:1)
我试图使用$ .Deferred
好!
但是我在这个地方遇到了循环问题:
$.each(data, recursion)
每个recursion(i)
调用都会返回一个承诺,所以当我们将它们踢掉时,我们会留下一系列承诺。现在,我们可以使用$.when
到wait for all of them,并取消对所有结果的承诺。
现在,我们使用then
在ajax调用之后链接这个循环执行,这样我们就可以为这个递归步骤的最终结果返回一个promise。
function recursion(i, x) {
return $.ajax('http://example.com/' + tree[i] + x).then(function (data) {
if (++i < tree.length)
// get an array of promises and compose all of them
return $.when.apply($, $.map(data, function(d) {
return recursion(i, d);
}));
else // at the innermost level
return data; // get the actual results
}); // and return a promise for that
}
答案 2 :(得分:0)
为简单起见,您可以在.done中运行一个函数来检查i的值,如果它等于树的长度(减去1),则运行您的函数。
很抱歉,这不包括异步性质......而是...创建一个跟踪已完成数量的变量,并与数组中的数字进行比较。如果相等,请运行您的功能。
答案 3 :(得分:0)
编辑,jquery deferred
,promise
实际上并不需要达到要求。请参阅下面的Bergi评论和链接。
尝试(此模式; 不带 jquery.deferred
或promise
)
(function recursion() {
var tree = [1, 2 ,3, 4]
, results = []
, dfd = function(res) {
alert('All calls are done!');
console.log(res)
};
$.each(tree, function(k, v) {
$.ajax("http://example.com/" + v)
.done(function (data, status, jqxhr) {
// data is array
results.push([data, status, jqxhr.state()]);
if (results.length === tree.length) {
dfd(results);
}
});
});
}());