2012-01-11 128 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

相關問題