如何将Redis哈希转换为JSON?

3
我正在使用node_redis为一个node服务提供redis中对象的JSON表示。我认为这对于很多人来说可能是相对基础的东西,但我卡住了。在遍历所有哈希并将它们存储之前,我就已经发送了响应。以下是coffeescript代码:
    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));

我不知道如何让我的代码在等待内部任务完成时进入休眠状态。我猜测有一些方法可以处理它,但我想不出来。谢谢大家。

1个回答

2

你正在迭代n个键并在调用client.keys后返回JSON.stringify(objects)(这将依次调用client.hgetall获取每个键的值?),但是在调用client.keys之后,您返回response.end(JSON.stringify(objects))。

问题很简单 - 你需要在从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请求中没有获得任何响应,那么它将超时,并且您将永远无法发出响应。最好更改您存储哈希值的方式,以便一次获取所有值,或者在一定时间后调用一个函数以发出响应,以便您的客户端不会永远等待。
请问为什么您选择使用coffeescript编写这个程序呢?当它通过这样的翻译层进行转换时,似乎写node.js会非常麻烦。

1
谢谢……这将解决我的问题。我想出了可能会延迟所有操作直到完成的某些模式,但以前我经常错了。关于“更改哈希存储方式”的建议,我始终乐于接受。我刚踏入非关系型数据库领域,我习惯于基于任意标准轻松抓取一堆“对象”。 - CircusNinja
我最初花了很长时间来研究如何构建我的数据结构,以便更容易地查询Redis。我发现自己写了很多带有“内部”和“外部”异步函数的节点代码,然后在最后呈现响应。最终,我改变了我的模式,这样我就可以提取数据,然后进行过滤。不过,这取决于您的用例,因为有合法的理由采用那种方式。 - tjarratt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接