Es gibt mindestens zwei Probleme in diesem Code:
-
Der erste ist mit dem Javascript-Closure-Management verknüpft. Der Rumpf einer Schleife erstellt keinen Gültigkeitsbereich. Bei Javascript liegt der Gültigkeitsbereich von Variablen auf Funktionsebene, nicht auf Blockebene. Sie müssen eine Funktion in die Schleife selbst einführen, um die Erstellung eines ordnungsgemäßen Abschlusses zu erzwingen. Weitere Informationen hier.
-
der zweite ist eine Wettlaufbedingung zwischen den Befehlen "exists" und "set". Wenn mehrere Redis-Verbindungen ausgeführt werden und Befehle auf denselben Tasten festgelegt werden, treten wahrscheinlich Konflikte auf. Anstelle von exists und set sollten Sie setnx verwenden, das die Prüfung und das Setzen in einer einzigen atomaren Operation durchführt.
In Ihrem zweiten Beispiel wurde das Schließungsproblem durch die Verwendung von forEach behoben, aber Sie generieren aufgrund der asynchronen Natur der Sprache immer noch alle Get-Operationen vor den Set-Operationen.
Wenn Sie wirklich alle Get- und Set-Operationen sequenzieren wollen (was übrigens viel langsamer sein wird), dann können Sie ein wenig funktionale Programmierung verwenden, um die Schleife mit Rekursion zu implementieren.
Beispiel :
Dieses Programm:
var redis = require('redis')
var rc = redis.createClient(6379, 'localhost');
var tags = [
"apple",
"tiger",
"mouse",
"apple",
"apple",
"apple",
"tiger",
"mouse",
"mouse",
];
var count = 0;
function loop(tags) {
function rec_loop(tags,i) {
if ( i >= tags.length )
return
rc.get("tag:"+tags[i],function(err,rr) {
console.log("get tag "+tags[i]+" result code "+rr);
if ( rr == null ) {
rc.set("tag:"+tags[i],"info",function(err,rr) {
count++;
console.log('set tag '+tags[i]+' '+rr+' objects count '+count);
rec_loop(tags,++i)
})
} else
rec_loop(tags,++i)
})
}
rec_loop(tags,0)
}
loop(tags)
zeigt:
get tag apple result code null
set tag apple OK objects count 1
get tag tiger result code null
set tag tiger OK objects count 2
get tag mouse result code null
set tag mouse OK objects count 3
get tag apple result code info
get tag apple result code info
get tag apple result code info
get tag tiger result code info
get tag mouse result code info
get tag mouse result code info
Beachten Sie, dass die Racebedingung in diesem Beispiel immer noch vorhanden ist. Sie sollten setnx verwenden, um diese Art von Prüf- und Set-Operationen zu implementieren.