理解递归函数的节点.js中的承诺
Understanding promises in node.js for recursive function
我正在尝试使用递归调用从 redis 中获取数据,在成员返回 null 时停止并返回。
所以我的数据是这样添加的:
SADD parents.<name> <parent1> <parent2>
SADD parents.<parent1> <grandparent1> <grandparent2>
...
最终数据应如下所示:
[
{
label: <name>,
parents: [
{ label: <parent1>,
parents: [ {label: <grandparent1>}, {label: <grandparent2> }] },
{ label: <parent2> }
]
}
]
这是我正在弄乱的代码(从不同的来源拼凑在一起),但我不知道我在做什么。 不确定这段代码是否有用,我可能偏离了轨道。
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 ))} );
我可以查看示例,从理论上看它应该如何工作,但我无法弄清楚它应该如何与 q 实现一起工作。 任何帮助将不胜感激。
- 在处理承诺时,尽量保持纯净。避免有副作用的函数,即操作其自身范围之外的任何变量。
- 避免将回调传递给函数。只将它们传递给承诺方法。您在
r_client.smembers()
和调用getFromRedis
方法时都执行此操作
我只能看到一个特定的错误,它会阻止您的脚本工作:
return [];
对回调没有任何影响。因此,在这种情况下,ret
永远不会得到解决。如果有的话,你会做ret.resolve([]); return;
。但是,有更好的解决方案可以让您再次使用return
。
要重组脚本,有两点:
- 使用
Q.nfcall
帮助程序函数(等)可避免直接处理回调样式的 API。然后使用then
转换其结果 - 同步返回树叶或后代获取计算的承诺。 - 首先使用
Q.all
,然后转换其结果。不要向每个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 ));
});
相关文章:
- React JS:未捕获(在承诺中)语法错误:在位置 0 的 JSON 中意外<令牌
- 如何判断请求/承诺是否需要超过5秒才能完成,angular js
- 因果报应,幻影JS和es6承诺
- Node.js-承诺和锥形语句(if、switch等)-如何构建
- Angular JS承诺和ng重复
- Node JS异步承诺.所有问题
- 处理角度.js承诺错误状态
- Node.JS-Q模块-承诺
- JS承诺:然后和捕获之间有什么区别
- 如何构建模块化的js承诺链
- Phantom.js-如何使用承诺而不是回调
- 这是使用承诺与 Sequelize.js的正确方法吗?
- Node.js承诺使用Q
- JS bluebird承诺错误没有给出任何细节
- 用q.js链接承诺
- 无法获得蓝鸟承诺和猫鼬的 save() 在 node.js 中工作
- 设置蓝鸟承诺分辨率.js最小延迟
- Angular JS承诺,JSON数据和有趣的时间
- 如何编写返回具有正确值的 Q 库承诺的 JS 函数
- 在nodejs中使用Q.js承诺进行循环的正确方法