Javascript 多个条件异步递归函数和jQuery承诺
我有一个复杂的递归javascript函数,在我需要开始使用异步函数(本例中是jQuery.ajax)之前,它一直工作得很好。我在下面包含了一些psuedo代码,这些代码给出了情况的要点。我希望使用承诺(而不是当前的回调)来实现这段代码,但无法解决如何处理递归和多个条件ajax调用。如果我正确理解了承诺,它们允许您在异步调用返回时执行操作,但是我如何处理下面的情况呢Javascript 多个条件异步递归函数和jQuery承诺,javascript,jquery,ajax,asynchronous,recursion,Javascript,Jquery,Ajax,Asynchronous,Recursion,我有一个复杂的递归javascript函数,在我需要开始使用异步函数(本例中是jQuery.ajax)之前,它一直工作得很好。我在下面包含了一些psuedo代码,这些代码给出了情况的要点。我希望使用承诺(而不是当前的回调)来实现这段代码,但无法解决如何处理递归和多个条件ajax调用。如果我正确理解了承诺,它们允许您在异步调用返回时执行操作,但是我如何处理下面的情况呢 function wrapperFunction(success,error) { var level = 0;
function wrapperFunction(success,error) {
var level = 0;
result = [];
var innerFunction = function(info,result,success,error) {
level++;
jQuery.ajax({
url: 'baseurl1' + info,
success: parseData,
error: error
});
function parseData(data) {
data.forEach( function(item) {
result.push(item.something);
if ( item.info ) {
innerFunction(item.info, result, success, error);
}
});
if ( data.condition ) {
jQuery.ajax({
url: 'baseurl2' + info,
success: parseData2,
error: error
});
}
function parseData2(data2) {
data2.forEach(function(item2) {
if ( item2.condition ) {
jQuery.ajax({
url: 'baseurl3' + info,
success: parseData3,
error: error
});
}
});
function parseData3(data3) {
if ( data3.condition ) {
jQuery.ajax({
url: 'baseurl4' + info,
success: parseData4,
error: error
});
}
function parseData4(data) {
result.push(data2.something + data4.something);
}
}
}
level--;
if (level == 0 && success) {
success(result);
}
}
}
innerFunction('rootinfo', result, success, error);
}
wrapperFunction(
function(data) {
// process success
},
function(err) {
// handle errors
}
}
正如我已经说过的,这只是伪代码。我最初是从我的真实代码中提取出来的,看看我是否能理解实际的结构。我知道如果ajax在同步的地方调用,它是可以工作的,但是现在它们是异步的,它只是有时工作(取决于调用返回的速度)
我如何使用承诺来实现这种情况
编辑
我刚刚研究出如何使用承诺序列化所有内容,虽然这是等待所有内容完成的一种方法,但我宁愿并行运行多个调用,然后找到一种等待所有内容完成的方法。我知道这是可能的承诺,但我不知道如何。在Sandeep Nayak的帮助下,我已经让它工作了(见上面的评论)。我想我为任何遇到类似问题的人发布了伪代码的工作版本 我基本上添加了两个级别的承诺(外部承诺和内部承诺),如果所有内部承诺都得到了解决,那么外部承诺就会得到解决。可能有清理代码的余地,但它可以按原样工作
function wrapperFunction(success,error) {
var level = 0;
var result = [];
var outerPromises = [];
var innerFunction = function(info,result,success,error) {
var outerPromise = new jQuery.Deferred();
outerPromises.push( outerPromise );
level++;
jQuery.ajax({
url: 'baseurl1' + info,
success: parseData,
error: error
});
function parseData(data) {
data.forEach( function(item) {
result.push(item.something);
if ( item.info ) {
innerFunction(item.info, result, success, error);
}
});
if ( data.condition ) {
jQuery.ajax({
url: 'baseurl2' + info,
success: parseData2,
error: error
});
} else {
outerPromise.resolve();
}
function parseData2(data2) {
var innerPromises = [];
data2.forEach(function(item2) {
var innerPromise = new jQuery.Deferred();
innerPromises.push( innerPromise );
if ( item2.condition ) {
jQuery.ajax({
url: 'baseurl3' + info,
success: parseData3,
error: error
});
} else {
innerPromise.resolve();
}
function parseData3(data3) {
if ( data3.condition ) {
jQuery.ajax({
url: 'baseurl4' + info,
success: parseData4,
error: error
});
} else {
innerPromise.resolve();
}
function parseData4(data) {
result.push(data2.something + data4.something);
innerPromise.resolve();
}
}
});
jQuery.when.apply(undefined, innerPromises).then( function() { outerPromise.resolve(); } );
}
level--;
if (level == 0 && success) {
jQuery.when.apply(undefined, outerPromises).then( function() { success(result); } );
}
}
}
innerFunction('rootinfo', result, success, error);
}
wrapperFunction(
function(data) {
// process success
},
function(err) {
// handle errors
}
}
你为什么要使用承诺?与你目前所拥有的相比,他们没有提供任何真正的好处。还要注意,这里没有递归。您可能可以整理代码以使其更加优雅,但这取决于每个函数所需的范围及其检索的数据。InnerFunction调用ajax查询,成功时调用parseData,在特定条件下调用InnerFunction。对我来说,这看起来像是递归。你可以这样做:这样你的AJAX调用将并行启动,然后我们可以等待所有承诺的实现resolve@RoryMcCrossan正如Chris所说,内部函数被反复调用。至于承诺,我不知何故需要一种方法,在继续之前等待所有ajax查询完成。如果你知道一种不用承诺就能做到这一点的方法,请随意分享。