2012-01-11 121 views
3

我正在使用node_redis为从redis获得的对象提供JSON表示形式的节点服务。我认为这可能是你很多人相对基本的东西,但我很难过。我得到了我发送我的回复之前我已经通过我所有的哈希和存储它们。这里的CoffeeScript的:如何将redis哈希转换为JSON?

objects = [] 
    client.keys 'objects*', (err,keys) -> 
     for key in keys 
     client.hgetall key, (err,obj) -> 
      objects.push obj 
    response.end JSON.stringify objects 

和生成的JavaScript:

 objects= []; 
     client.keys('objects*', function(err, keys) { 
     var key, _i, _len, _results; 
     _results = []; 
     for (_i = 0, _len = keys.length; _i < _len; _i++) { 
      key = keys[_i]; 
      _results.push(client.hgetall(key, function(err, obj) { 
      return objects.push(obj); 
      })); 
     } 
     return _results; 
     }); 
     return response.end(JSON.stringify(objects)); 

我不知道如何把我的代码在度假,而它等待内的东西来完成。我怀疑有办法处理它,但我想不出任何事情。谢谢大家。

回答

2

因此,您在调用n个键,然后在调用client.keys(它将依次为每个键调用client.hgetall?)之后返回JSON.stringify(对象),但是然后返回response.end( JSON.stringify(objects))在调用client.keys之后。

问题很简单 - 您需要在附加hgetkeys结果的函数内部呈现响应,但只有在您看到所有来自hgetkeys的响应后才会响应。

我不是CoffeeScript的爱好者,但这里的一个JavaScript版本应该工作:

objects= []; 
    client.keys('objects*', function(err, keys) { 
    var key, _i, _len, seen; 
    seen = 0; 
    for (_i = 0, _len = keys.length; _i < _len; _i++) { 
     key = keys[_i]; 
     client.hgetall(key, function(err, obj) { 
     objects.push(obj); 
     seen++; 
     if (seen == len) { 
      return response.end(JSON.stringify(objects)); 
     } 
     }); 
    } 
    }); 

我要指出,一个缺点是,如果你永远不会从hgetall之一的响应请求,这将超时,你永远不会发出响应。改变存储哈希值的方式可能会更好,因此您可以一次获取所有值,或者在一段时间后调用一个函数来发出响应,以便客户端不会永远等待。

请问你为什么选择在咖啡书写这个?当它通过像这样的翻译层时,编写节点似乎是一件非常头痛的事情。

+1

谢谢......这*将解决我的问题。我认为有一些我错过的模式会延迟进一步的执行,直到所有事情都完成了,但我以前错了很多次。关于“改变你如何储存哈希”,我总是乐于接受建议。我刚刚从关系数据库领域脱颖而出,而且我习惯于根据任意标准轻松获取一堆“对象”。 – CircusNinja 2012-01-12 03:13:05

+0

我用redis花了一段时间,最初试图弄清楚如何构建我的数据以便查询。我发现自己写了很多带有“内部”和“外部”异步函数的节点代码,然后在最后呈现响应。最终改变了我的模式,所以我可以将数据拉入,然后过滤它。尽管如此,取决于你的使用案例,这样做有合理的理由。 – tjarratt 2012-01-12 17:34:50

相关问题