Javascript 理解node.js中递归函数的承诺
我尝试使用递归调用从redis中获取数据,在成员返回null时停止并返回 因此,我的数据是这样添加的:Javascript 理解node.js中递归函数的承诺,javascript,node.js,recursion,promise,Javascript,Node.js,Recursion,Promise,我尝试使用递归调用从redis中获取数据,在成员返回null时停止并返回 因此,我的数据是这样添加的: SADD parents.<name> <parent1> <parent2> SADD parents.<parent1> <grandparent1> <grandparent2> ... 我可以看看这些例子,从理论上看它应该如何工作,但我不能确定它应该如何与q实现一起工作。任何帮助都将不胜感激。 在与承诺打交道时,
SADD parents.<name> <parent1> <parent2>
SADD parents.<parent1> <grandparent1> <grandparent2>
...
我可以看看这些例子,从理论上看它应该如何工作,但我不能确定它应该如何与q实现一起工作。任何帮助都将不胜感激。- 在与承诺打交道时,尽量保持纯洁。避免使用有副作用的函数,即操作其自身范围之外的任何变量
- 避免将回调传递给函数。只将它们传递给promise方法。您可以使用
和调用r\u client.smembers()
方法来执行此操作getFromRedis
return [];
不受回调的任何影响。因此,在这种情况下,ret
永远不会得到解决。您将执行ret.resolve([]);返回代码>如果有。但是,有更好的解决方案可以让您再次使用return
要重新构造脚本,有两点:
- 使用(等)避免直接处理回调样式的API。使用
then
转换其结果,然后同步返回树叶或保证后代获得计算
- 首先使用,然后转换其结果。不要向每个
依赖项添加处理程序,而是在一个步骤中获得整个结果并构建构造
你以前有基于回调的解决方案吗?没有。我试过,但它更复杂。更简洁。当我看到它像这样工作时,这一切都是有道理的。出于某种原因,当我从命令行运行它时,它从不返回任何输出?这就像是陷入了一个循环。添加一些日志,看看你在这段时间里得到了什么,也许真的有。我不太了解redis,可能是因为我没有正确地从值构造查询-请参阅代码部分,您可能需要对其进行调整。似乎它应该可以工作,但我在q.js中发现了一个错误:TypeError:Object在exports.commands.forEach.RedisClient.(匿名函数)在Promise.Promise.apply中没有方法“sendCommand”。(/Users/username/node\u modules/node redis/index.js:408:12)(~/node\u modules/q/q.js:752:41)at Promise.dispatch(~/node\u modules/q/q.js:1337:14)at flush(~/node\u modules/q/q.js:108:17)at process.startup.processNextTick.process.\u tickCallback(node.js:244:9)
我做过的一件事(无论哪种方式我都会得到错误):smembers从Redis取回缓冲区而不是字符串。因此我调用了“par”上的toString()。哦,找到了。我将Q.nfcall()更改为:return Q.ninvoke(r_client,“smembers”,“parents.”+nodeName)。然后(函数(val){
为了解决这个问题,我三天的大部分时间都在拼命工作。非常感谢你的帮助。
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 ))} );
return [];
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 ));
});