2012-04-04 4 views
1

Ich benutze Node.js w/node_redis und bin ein durch ein Objekt durchlaufen und nach Daten in Redis suchen, dann Ergebnisse zurückgeben.For-Schleife, die Elemente von Redis-Verzögerung erhalten

Ich habe es Setup wie folgt aus:

 for (var key in items) { 
      if (items.hasOwnProperty(key)) { 

        app.client.llen(items[key].id+'_click', function(err, total) { 
         items[key].total = total; 

        }); 
      } 
     } 

     callback(items); 

Das Problem ist, dass es eine Schleife durch, bevor der Anruf abgeschlossen Redis. So wird der Callback aufgerufen, bevor er tatsächlich den Gesamtwert aktualisiert. Es scheint auch einige Elemente aufgrund der Verzögerung zu überspringen.

Gibt es einen besseren Weg, damit umzugehen?

Vielen Dank!

EDIT:

Ok, so habe ich es wie folgt aktualisiert:

getTotal(function() { 
     callback(items); 
    }); 

    getTotal = function (callback) { 

     var count = 1; 

     for (var key in items) { 
      if (items.hasOwnProperty(key)) { 
       app.client.llen(items[key].id + '_click', function (err, total) { 
        items[key].total = total; 

        if (items.length == count) { 
         callback(); 
        } 

        count++; 
       }); 
      }; 
     } 

Dies scheint, wie es funktionieren würde, es löst den Rückruf zu gegebener Zeit jedoch scheint es, nur die letzte Der Schlüssel wird insgesamt aktualisiert.

+0

Haben Sie rekursive Version versucht? –

+0

Hm, innerhalb der for-Schleife oder als Ersatz dafür? – dzm

Antwort

2

Ihr erstes Beispiel funktioniert nicht, da eine Schleife synchron ist, während die Redis-Clientaufrufe asynchron sind. Ihr zweites Beispiel funktioniert nicht viel besser wegen der Javascript-Schließungsverwaltung. Sie benötigen einen korrekten Bereich in der Schleife selbst, damit die Schließung korrekt gehandhabt wird und alle Gesamtfelder entsprechend aktualisiert werden.

Mit forEach scheint hier einfacher zu sein:

getTotal = function (callback) { 
    var count = 0; 
    Object.keys(items).forEach(function(key) { 
    ++count; 
    app.client.llen(items[key].id + '_click', function (err, total) { 
     items[key].total = total; 
     if (--count == 0) { 
     callback(items); 
     } 
    }) 
    }) 
} 

getTotal(function(items) { 
    console.log(items); 
}) 
+0

Danke für Ihre Antwort! Ich war in einem ähnlichen Problem stecken und Ihr Code gab mir die Hinweise, die ich brauchte, um meine Sachen zum Laufen zu bringen. – andyengle