Javascript递归函数-在左级调用异步函数
Javascript recursive function - call to asynchronous function at the leave level
在下面的程序中,当最初调用recurse(prog)
(第64行)时,它递归地挖掘prog
(第1行)中描述的表达式exp
,在exp.type = A, B或c之间切换。
在递归调用的最底层(当case("C")),我调用查找collections
列表的verySlowMan(exp.value)
,以检查具有exp.value名称的集合是否存在。
如果是,则返回集合
如果没有,则返回一个新的Error
问题是verySlowMan()
花了他的时间来检索集合。
为简单起见,我设置了一个简单的if else
条件,但verySlowMan
最终将发出XHR请求。所以它是不可预测的慢
问题如下:
如何将verySlowMan的返回值一直传播到递归调用,以获得一个很好的集合列表作为调用recurse(prog)的结果?
目前,由于可以理解的原因,我得到[null, [null, null], null]。但是我真的不知道如何解决它。
我试图返回一个延迟的。从verySlowMan
的承诺,但在这种情况下,我认为recurse()也应该为每个递归调用返回一个新的承诺。
(1)我不确定如何使这个正确
我怀疑这是不是最好的办法注意:prog
, collections
和recurse()中的case中的项目数量可能会变得非常长。
程序如下:
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 ]
下面是一个带有承诺的例子。
function verySlowMan( collectionToFind ) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
for(var i = 0; i < collections.length; i++) {
if ( collections[i].name === collectionToFind ) {
resolve(collections[i]);
return;
}
}
reject(new Error("No Collection"));
}, 100);
});
}
function recurse(exp){
function errorHandler(err) {
if(err.message === "No Collection") return null;
else throw err;
};
switch(exp.type){
case("A"):
return Promise.all(exp.value.map(recurse));
case("B"):
if (typeof(exp.value) === 'string') {
return verySlowMan(exp.value).catch(errorHandler);
} else {
return Promise.all(exp.value.map(recurse));
}
case("C"):
return verySlowMan( exp.value ).catch(errorHandler);
default:
return Promise.reject(new Error('wrong type'));
}
}
recurse(prog).then(function(result) {
console.log(result);
}).catch(function(err) {
console.log(err.stack);
});
相关文章:
- jasmine 2-在jasmine指定的超时时间内未调用异步回调.DEFAULT_TIMEOUT_INTERVAL
- 递归调用异步函数
- Fine Uploader S3-无处安全调用异步“;setUploadSuccessParams()"
- 调用异步函数的循环
- 从视图调用异步加载模块函数
- 在循环中调用异步函数
- JavaScript ES6 承诺在 while 循环中调用异步操作
- 并行调用异步/等待函数
- 解析云代码:如何调用异步保存的承诺
- 量角器根据条件单击嵌套元素,错误 - 在指定的超时内未调用异步回调
- 反应组件调用了两次(AJAX调用异步)
- 使用 ajax 调用异步 Web api 方法
- NodeJS:调用异步函数时谁做异步工作
- 调用异步函数 befrore 服务器开始侦听
- Node JS 动态集合 ajax 调用异步等待
- 页面重定向后调用异步成功函数
- 如何在调用异步Web服务响应时将值设置为数组
- 如何在node.js可读流中调用异步函数
- 在nodejs中,是否有更好的设计模式来同步调用异步函数
- 同步调用异步 JavaScript 函数