2013-05-20 120 views
3

我試圖從redis實例中獲得一堆密鑰。我正在使用node-redis。我正在使用一個循環:使用node-redis獲取多個密鑰

for(var i=1; i<=num; ++i){ 
    client.get(key + ':' + num, function (err, reply) { 
     obj[num] = reply; 
    }); 
} 
return obj; 

obj只是未定義。我覺得我可能會有問題,因爲get顯然是異步調用的。是否有另一種方法來實現這一目標?我應該只將值存儲在有序集中嗎?

+1

凡'obj'聲明? – Ian

回答

10

我將根據代碼界面和您的評論client.get()是異步的猜測冒險。這意味着它會調用「稍後」傳遞給它的回調函數,而不是立即。因此,您不能使用同步編碼模式來收集多次調用client.get()的結果,因爲函數返回時obj中的結果尚不可用。因此obj尚未填充結果。

如果您想知道何時完成多個異步調用,那麼您必須採用完全不同的方式進行編碼。而且,結果只能在回調函數中使用,而不能在函數結束時使用。

總之,我看到多個問題與您的代碼:

  1. client.get()是異步的,因此尚未結束時,你的函數返回
  2. 你或許應該使用i,不numclient.get()調用,以便每次通過for循環都會生成不同的請求。
  3. 循環中的值i必須在閉包中凍結,以便保留它在稍後調用的回調函數中使用的值。
  4. 如果obj實際上未定義,那可能是因爲您沒有將它初始化爲空對象。

下面是做這件事:

var obj = {}; 
var remaining = num; 
for(var i=1; i<=num; ++i){ 
    // create a closure here to freeze the value of i in the callback 
    (function(i) { 
     client.get(key + ':' + i, function (err, reply) { 
      obj[i] = reply; 
      // see if all asynch calls are done yet 
      --remaining; 
      if (remaining === 0) { 
       // all asynch calls to client.get() are done now 
       // in here, you can use the obj object and the results put on it 
      } 
     }); 
    })(i); 
} 
+0

是的,我認爲這可能是一個異步問題。而'i''和'num'只是我輸入問題的一個錯誤。而你的解決方案非常好,謝謝你。 – alf

+0

清晰簡潔 –