21 Stimmen

For-Schleife und asynchroner Rückruf in node.js?

Ich bin neu in JavaScript und in node.js. Ich möchte eine Schleife durch ein Verzeichnis und fügen Sie alle Datei stat (nicht andere Verzeichnisse) zu einem Array. Wie Sie unten sehen, gibt es ein Problem mit meinem Code, da der Callback wahrscheinlich aufgerufen wird, nachdem die for-Schleife beendet ist, so dass die Verwendung der "i"-Variable in der Callback-Methode nicht funktionieren wird. Aber wie sollte der Code aussehen, damit das untenstehende Snippet funktioniert? Hat es etwas mit Closures zu tun?

Danke für die Hilfe!

    fs.readdir(SYNCDIR, function(err1, files) {
        var filesOnly = [];

        if(!err1) {

            for(var i = 0; i < files.length; i++) {

                var imgFilePath = SYNCDIR + '/' + files[i];
                fs.stat(imgFilePath, function(stat){

                    if (stat.isFile()){
                        filesOnly[i] = stat; // This will not be correct since the for-loop has finished
                    }
                });

            }
        }
    });

0 Stimmen

Ich glaube, dass Node seit Ihrem Posting einige Synch-Funktionen zum fs-Namensraum hinzugefügt hat.

0 Stimmen

32voto

Gary Chambers Punkte 23404

Sie haben Recht, dass man einen Verschluss verwenden muss. Sie sollten den Inhalt der Datei for Schleife in einer selbst-aufrufenden Funktion, um den Wert von i für jede Iteration.

fs.readdir(SYNCDIR, function(err1, files) {
    var filesOnly = [];

    if(!err1) {

        for(var i = 0; i < files.length; i++) {

            (function(i) {
                var imgFilePath = SYNCDIR + '/' + files[i];
                fs.stat(imgFilePath, function(stat){
                    if (stat.isFile()){
                        filesOnly[i] = stat;
                    }
                });
            })(i);

        }
    }
});

0 Stimmen

Vielen Dank. Hat mir sehr geholfen.

10voto

einaros Punkte 641

Eine Möglichkeit besteht darin, das Innere der Schleife umzuschreiben, um einen Abschluss zu verwenden:

fs.readdir(SYNCDIR, function(err1, files) {
    var filesOnly = [];
    if(!err1) {
        for(var i = 0; i < files.length; i++) {
            (function(index) {
                var imgFilePath = SYNCDIR + '/' + files[index];
                fs.stat(imgFilePath, function(stat){
                    if (stat.isFile()){
                        filesOnly[index] = stat;
                    }
                });
            })(i);
        }
    }
});

Ein besser aussehendes Beispiel, das das Gleiche erreicht, indem Array.prototype.forEach verwendet wird:

fs.readdir(SYNCDIR, function(err1, files) {
    var filesOnly = [];
    if(!err1) {
        files.forEach(function(file, i) {
            var imgFilePath = SYNCDIR + '/' + file;
            fs.stat(imgFilePath, function(stat){
                if (stat.isFile()){
                    filesOnly[i] = stat;
                }
            });
        });
    }
});

3 Stimmen

+1 für die .forEach Ansatz. Es ist viel einfacher, und vermeidet die Erstellung eines neuen gebundenen Bereichs für jede Iteration.

0voto

Rob Tweed Punkte 79

Alternativ können Sie auch das neue Threads-Modul ( https://github.com/robtweed/Q-Oper8 ), und dann können Sie all diese Dinge viel einfacher mit standardmäßiger synchroner Kodierung innerhalb der Threads-Kind-Prozesse erledigen, da sie jeweils nur die Anfrage eines Benutzers bearbeiten.

Asynchrone Logik und verschachtelte Rückrufe ade!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X