执行的函数的递归异步Ajax调用
我需要递归异步Ajax调用后执行功能之后。 我:执行的函数的递归异步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 $的jQuery,但AJAX调用返回的承诺太。 我试图使用$ .Deferred但我在这个地方遇到了问题循环:
$.each(data, function() {
recursion(i);
});
请帮助我。
我试图使用$ .Deferred
好!
,但我遇到了在这个地方循环的一个问题:
$.each(data, recursion)
每个recursion(i)
调用返回一个承诺,所以当我们踢他们离我们只剩下诺言的集合。现在,我们可以使用$.when
至wait for all of them,并取回所有结果的承诺。
现在,我们使用then
在ajax调用之后链接这个循环执行,以便我们可以返回此递归步骤最终结果的承诺。
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
}
你的答案陷入循环:(,冻结浏览器,当在'console',此页面尝试;没有返回结果在jsfiddle http://jsfiddle.net/guest271314/x8a8brak /?如果可能,可以在上面创建一个jsfiddle,以展示预期的结果?fwiw,为什么不简单地撰写和发布_own_答案而不是检查其他用户的努力_before_发布自己的答案?或者两者都有?如果您的方法/答案是真正最有效的答案,答案会说明问题,不是吗?可能有更多的方式,或“模式”,以达到相同的结果? – guest271314 2014-08-28 17:05:49
我认为你有一个错误1你的'if(++ i ...'当'++ i'等于'tree.length'时,那么'tree [i]'在调用'recursion'时将是未定义的。你也定义了一个参数'x',但从来没有通过它。这是否意味着无论从循环中的“数据”中提取哪些信息? – 2014-08-28 17:44:45
@ guest271314对于它的价值,我非常感谢Bergi对我的回答的评论,并因此改进了我对未来承诺的使用。我认为我在解决他的评论时迟缓导致他发布自己的答案。我自己也经常做同样的事情。如果答案类似于我会回答的问题,但是会漏掉几个关键点,我会将它们指出来,让答案者更新他的答案,而不是发布类似的答案。如果回答者不在(或者不愿意)更新,我会发布我自己的。 – 2014-08-28 17:51:49
为简单起见,你可以只运行在你的.done一个函数,检查i的值,如果它等于树的长度(减1),然后运行你的函数。
对不起,这不包括异步性...,而不是...创建跟踪的完成数的变量,并比较数组中的号码。当相等时,运行你的功能。
虽然这并没有使用承诺的力量。 – Bergi 2014-08-28 14:26:18
只是一个简单的方法来完成工作。对不起,我还没有使用承诺。 – 2014-08-28 14:26:50
@Shane Stebner,是的,但是在循环中存在问题,在最后一步树中[3],当我检查“i”时,这个条件将会像数据数组中的元素那样执行多少 – BottieYOYO 2014-08-28 14:42:26
你需要做这样的事情:
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
}
});
}
目前未经测试,但它至少给你的想法。基本上,只有解决了所有后续调用后才能解决延期问题。
请勿使用[deferred antipattern](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#wiki-the-deferred-anti-pattern)!你甚至知道['$ .when'](http://api.jquery.com/jQuery.when/)! – Bergi 2014-08-28 15:43:28
@Bergi我觉得我可能在这种情况下失去了一些愚蠢的东西,但是你打电话给'什么时候'?在函数返回并且ajax调用解析不充分时,延迟列表不存在,因为这太快了。 – 2014-08-28 15:49:44
但是ajax承诺确实存在,你只需要[链接](http://api.jquery.com/deferred.then/)你的递归调用,这些调用被'$ .when'捆绑在一起。可能我的评论是误导性的,你使用'.when'是正确的,使用'def'和'ajax()。done(...)'不是。 – Bergi 2014-08-28 16:01:15
编辑,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);
}
});
});
}());
为什么你从IIFE返回字符串“pending”? – Bergi 2014-08-28 15:41:05
请勿使用[deferred antipattern](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#wiki-the-deferred-anti-pattern)!已经有[一个功能来做这个](http://api.jquery.com/jQuery.when/)。 – Bergi 2014-08-28 15:41:48
在完成所有任务之前,'pending'是'deferred.state()'。最好是完全从这个延期退出?将重新撰写并发布_without_延迟。谢谢 – guest271314 2014-08-28 15:45:26
你的'recursion()'甚至不返回一个承诺。 – Bergi 2014-08-28 14:22:44
看看[这个问题](http://stackoverflow.com/q/21762982/1048572)虽然和[这里](http:// stackoverflow。com/q/5627284/1048572)关于如何等待多个'recurse()'承诺 – Bergi 2014-08-28 14:25:42
为什么当递归调用实际上不使用'data'时,为什么递归调用循环的'data'呢? ?它是否需要递归?您可能想发布您的实际代码。 – Bergi 2014-08-28 14:27:36