[英]Understanding promises in node.js for recursive function
I'm trying to use recursive calls to get data out of redis, stopping and returning when the members return null. 我正在尝试使用递归调用从redis中获取数据,在成员返回null时停止并返回。
So my data is added like this: 所以我的数据添加如下:
SADD parents.<name> <parent1> <parent2>
SADD parents.<parent1> <grandparent1> <grandparent2>
...
And the final data should look like: 最终数据应如下所示:
[
{
label: <name>,
parents: [
{ label: <parent1>,
parents: [ {label: <grandparent1>}, {label: <grandparent2> }] },
{ label: <parent2> }
]
}
]
Here's the code I'm messing with (sort of cobbled together from different sources), but I have no idea what I'm doing. 这是我正在搞乱的代码(有点从不同的来源拼凑而成),但我不知道我在做什么。 Not sure if this code is even useful, I could be way off track.
不确定这段代码是否有用,我可能会偏离轨道。
var redis = require('node-redis');
var r_client = redis.createClient();
var Q = require('q');
function getFromRedis(nodeName){
var ret = Q.defer();
r_client.smembers('parents.' + nodeName,function(err,val){
if (err) ret.reject(err);
else {
var constructedObject={}; //this is our returned object
var dependents=[];
if (val)
{
for (var k in val){ //iterate the keys in val
constructedObject.name = val[k];
dependents.push(getFromRedis(val[k])
.then(function(subVal){
constructedObject[k]=subVal;
return ret.promise;
})
);
}
}
else { return [] }
}
Q.all(dependents)
.then(function(){ret.resolve(constructedObject);},ret.reject.bind(ret));
});
return ret;
}
getFromRedis( 'greg', function(out) {console.log('Final output: ' + JSON.stringify( out ))} );
I can look at the examples and see theoretically how it's supposed to work, but I can't get my mind around how it should work with the q implementation. 我可以看看这些例子,从理论上看它应该如何工作,但是我无法理解它应该如何与q实现一起工作。 Any help would be greatly appreciated.
任何帮助将不胜感激。
r_client.smembers()
and when invoking your getFromRedis
method r_client.smembers()
和调用getFromRedis
方法执行此操作 I can see only one specific mistake that would keep your script from working: 我只能看到一个会阻止你的脚本工作的特定错误:
return [];
does not have any effect from the callback. 回调没有任何影响。 So,
ret
is never going to be resolved in this case. 因此,在这种情况下,
ret
永远不会得到解决。 You would do ret.resolve([]); return;
你会做
ret.resolve([]); return;
ret.resolve([]); return;
if at all. 如果有的话。 However, there are better solutions that let you use
return
again. 但是,有更好的解决方案可以让您再次使用
return
。
To restructure your script, there are two points: 要重构脚本,有两点:
Q.nfcall
helper function (and the like) to avoid dealing with callback-style APIs directly. Q.nfcall
辅助函数 (等)可以避免直接处理回调式API。 Use then
to transform its result then - synchronously returning the tree leaves or a promise for the descendant-getting computations. then
使用then
转换其结果 - 同步返回树叶或后代获取计算的承诺。 Q.all
first, and then transform its result. Q.all
,然后转换其结果。 Don't add a handler to each dependent
, but get the whole result and build the construct
in one single step. dependent
项添加处理程序,而是获取整个结果并在一个步骤中构建construct
。 function getFromRedis(nodeName){
return Q.ninvoke(r_client, "smembers", 'parents.' + nodeName).then(function(val) {
// this is our returned object
var constructedObject = {label: nodeName};
if (val) {
var dependents = val.map(function(par) {
// get a promise for the next level
return getFromRedis(nodeName+"."+par.toString());
});
return Q.all(dependents).then(function(dependentResults) {
constructedObject.parents = dependentResults;
return constructedObject;
});
} else {
return constructedObject; // without parents
}
});
}
getFromRedis( 'greg' ).done(function(out) {
console.log('Final output: ' + JSON.stringify( out ));
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.