2012-03-14 64 views
1

我有執行我的程序很大的問題。 我們使用Redis的HKEY和測試,如果該鍵存在問題線程函數執行nodejs/redis

hgetall tags 
"X5" 
"6" 
"X2" 
"7" 

這是程序:

function firstChoiceChannel(){ 
     var i=0; 
     var listRep 
     console.log(tags); 
     for(var k in tags){ 
      console.log('@'+k+'|'+tags[k]); 
      client.hexists('tags',tags[k],function(err,rep){ 
       console.log(tags[k]+"=>"+k+' i '+rep) 
       if(rep===1){ 
         client.hget('tags',tags[k],function(err,rep){ 
          console.log('value:'+rep); 
         }) 
         console.log('ok'); 
       } 
      }); 
     } 
    } 

這個控制檯

[ 'X1', 'X2', 'X3', 'X5' ] 
@0|X1 
@1|X2 
@2|X3 
@3|X5 
X5=>3 i 0 
X5=>3 i 1 
ok 
X5=>3 i 0 
X5=>3 i 1 
ok 
value:7 
value:7 

執行程序爲什麼變量標籤[K]在子函數client.hexists(... function(err,rep){}) 總是等於表的最後一個值?

感謝您的幫助

文森特

回答

2

這是因爲client.hexists是異步的,所以回調的執行時,for循環已經結束。解決這個問題的最簡單的方法是打出來的功能:

function getIfExists(tag) { 
    client.hexists('tags', tag, function(err,rep) { 
    if(rep===1){ 
     client.hget('tags',tag,function(err,rep) { 
     console.log('value:'+rep); 
     }); 
    } 
    }); 
} 

此外,JavaScript的for... in...語法是不是最佳的陣列。

for(var i = 0, len = tags.length; i < len; i++) { 
    getIfExists(tags[i]); 
} 

或者你可以使用Array.prototype.forEach

tags.forEach(getIfExists); 

這麼說,我不知道爲什麼你做的hexists呢?你可以只是hget它,你會得到null或價值。

+0

它只是測試;)非常感謝 – Vsplit 2012-03-14 10:43:18

+0

你認爲它的功能是異步的(沒有測試)? – Vsplit 2012-03-14 20:41:43

+0

任何函數都不會返回它的答案,而是需要一個與答案一起調用的回調函數,(很可能)是異步的。 ['async'](https://github.com/caolan/async)對於這些事情來說是一個非常好的控制流程庫。 – 2012-03-15 10:56:55