2012-01-11 1 views
3

Я использую node_redis для предоставления услуги узла с представлением JSON объектов, которые я получаю от redis. Я думаю, что это, вероятно, относительно базовый материал для многих из вас, но я в тупике. Я дошел до того момента, когда отправлю свой ответ до Я прошел через все свои хэши и сохранил их. Вот 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 ключам, а затем возвращаете JSON.stringify (объекты) после вызова client.keys (который, в свою очередь, вызывает client.hgetall для каждого ключа?), Но затем вы возвращаете response.end (JSON.stringify (объекты)) после вызова 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 запросов, это будет тайм-аут, и вы никогда не получите ответ. Возможно, было бы лучше изменить, как вы храните свои хеши, чтобы сразу получить все значения или получить функцию, которую вы вызываете через определенное время, чтобы исправить ответ, чтобы ваш клиент не ожидал навсегда.

Могу ли я спросить, почему вы решили написать это в coffeescript? Кажется, что огромная головная боль для записи узла, когда он проходит через такой слой перевода.

+1

спасибо ... этот * будет * решите мой проблема. Я подумал, что есть какая-то картина, которую я отсутствовал, что задерживает дальнейшее исполнение, пока все не будет сделано, но я ошибался много раз. Что касается «изменения того, как вы храните хэши», я всегда готов к предложениям. Я недавно вышел из реляционной DB-земли, и я привык к легкому захвату кучи «объектов» на основе любых произвольных критериев. – CircusNinja

+0

Я потратил время, когда redis изначально пытался выяснить, как структурировать мои данные, поэтому было проще запросить. Я обнаружил, что написал много кода узла с «внутренними» и «внешними» асинхронными функциями, а затем создавал ответ в конце. В конечном итоге изменилась моя схема, чтобы я мог потянуть данные, а затем отфильтровать их. В зависимости от вашего варианта использования, есть законные причины для этого. – tjarratt