【发布时间】:2025-12-31 15:30:07
【问题描述】:
在下面的程序中,当最初调用recurse(prog)(第64行)时,它递归地挖掘prog(第1行)中描述的表达式exp,在exp.type = A的情况之间切换, B 或 C。
在递归调用的最底层(当 case("C") 时),我调用 verySlowMan(exp.value) 查找 collections 的列表以检查名称为 exp.value 的集合是否存在或不。
如果是,则返回集合
如果不是,则返回一个新的Error
问题是verySlowMan() 花时间检索一个集合。
为简单起见,我做了一个简单的if else 条件,但verySlowMan 最终会发出一个XHR 请求。所以速度出乎意料地慢
问题如下:
如何将verySlowMan 的返回值一直传播到递归调用中,以通过调用recurse(prog) 获得一个不错的集合列表?
目前,出于可以理解的原因,我得到 [ null, [ null, null ], null ]。但是我真的不知道如何解决它。
我试图从verySlowMan 返回一个 deferred.promises,但在这种情况下,我认为 recurse() 也应该为每个递归调用返回一个新的 Promise。
(1) 我不知道如何正确地做到这一点
(2) 我怀疑这是最好的方法
注意:prog、collections 中的项目数量以及 recurse() 中的案例可能会变得很长。
这是程序:
var prog = {
type : "A", value : [
{ type : "B", value : "C1" },
{ type : "B", value : [
{ type : "C", value : "C2" },
{ type : "C", value : "end" }
]},
{ type : "B", value : "C3" }
]
}
var collections = [
{ name : "C1", data : ["item1", "item2", "item3"]},
{ name : "C2", data : ["item1", "item2", "item3"]}
]
function verySlowMan( collectionToFind ){
collections.forEach(function(collection){
if ( collection.name === collectionToFind ) {
return collection;
}else{
return new Error("No Collection");
}
});
return null;
}
function recurse(exp){
switch(exp.type){
case("A"):
var As = [];
exp.value.forEach( function(B){
As.push ( recurse(B) );
} );
return As;
break;
case("B"):
var Bs = [];
if (typeof(exp.value) === 'string') {
return verySlowMan( exp.value );
} else {
exp.value.forEach( function(C){
Bs.push ( recurse(C) );
} );
return Bs;
}
break;
case("C"):
return verySlowMan( exp.value );
break;
default:
throw new Error('wrong type');
}
}
console.log( recurse(prog) ); // -> [ null, [ null, null ], null ]
【问题讨论】:
-
您的样本的预期输出是什么?似乎总是应该
throw new Error -
当你在
forEach回调中返回时 - 它不会从forEach运行的函数返回 -
你将不得不使用回调,并且整个递归函数将在回调中返回结果,如果这适合你的用例
-
在您的示例中,verySlowMan 不是异步的。这使您的代码令人困惑。另外,您想使用普通回调还是使用 Promise?如果内部也调用异步代码,则需要以异步样式编写所有循环和递归函数调用。
标签: javascript asynchronous recursion