2017-08-24 2 views
2

Ich habe, was ich ein seltsames Problem nennen .. Ich denke, Es ist im Zusammenhang, wie Knoten arbeitet asynchron, aber ich kann nicht herausfinden, wie es zu lösen ..NodeJS fs.stat innerhalb einer Schleife

ich habe den folgenden Code:

function traverse(dir) { 

console.log("START: " + dir); 

fs.readdir(dir, function(err, list) { 

    list.forEach(function(element) { 
     path = dir + "/" + element 

     console.log("Loop files/folders : " + path); 

     fs.stat(path, function(err, stats,) { 

      console.log("fs.stats file path : " + path + " : " + stats.isDirectory()) 
     }); 
    }, this); 
}); 

} 

Dies ergibt die folgende Ausgabe:

START: ./data/2017 
Loop files/folders : ./data/2017/.DS_Store 
Loop files/folders : ./data/2017/1 
Loop files/folders : ./data/2017/2 
Loop files/folders : ./data/2017/3 
Loop files/folders : ./data/2017/Arendal2017.pptx 
fs.stats file path : ./data/2017/Arendal2017.pptx : false 
fs.stats file path : ./data/2017/Arendal2017.pptx : true 
fs.stats file path : ./data/2017/Arendal2017.pptx : true 
fs.stats file path : ./data/2017/Arendal2017.pptx : true 
fs.stats file path : ./data/2017/Arendal2017.pptx : false 

Wie Sie aus dem Code sehen können, zunächst nur, dass ich in der Schleife eine Ausgabe der Pfadzeichenfolge geben. Innerhalb dieser Schleife mache ich dann einen Stat für jeden Pfad (Element) innerhalb des Directors. Was passiert, wenn ich die Pfadvariable im fs.stat-Callback verwende, bezieht sich dies auf die letzte Datei "Arendal" und nicht auf jedes einzelne Element in der Schleife. Die isDirectory bool ist eigentlich richtig nach der Liste der Dateien und Verzeichnisse, aber es ist auch wichtig für mich, den richtigen Pfad mit dem angegebenen isDirectory bool ..

So lösen Sie das?

Antwort

4

Das Problem hier ist, dass Sie die Variable path nicht im richtigen Bereich deklarieren.

Code ändern zu

list.forEach(function(element) { 
    var path = dir + "/" + element; // <=== DECLARE IT HERE 

    console.log("Loop files/folders : " + path); 

    fs.stat(path, function(err, stats,) { 

     console.log("fs.stats file path : " + path + " : " + stats.isDirectory()) 
    }); 
}, this); 

Für diese Art von Angebot, es ist nur ein Befehlszeilenprogramm unter der Annahme, könnte man, indem einfach die synchronen Funktionen von fs ein klareres Protokoll erhalten (so dass die Reihenfolge der Anrufe wird in Protokollen aufbewahrt).

+0

Perfekt, löste mein Problem. Eigentlich nicht nur ein Kommandozeilen-Tool. Es wird versucht, ein "intelligentes" Synchronisierungstool für sehr große Dateistrukturen/viele Dateien mit AWS zu erstellen. Ich denke, async ich vorteilhaft. – chranmat

+0

@chranmat Dann würde ich vorschlagen, dass Sie sich Versprechungen anschauen und async/erwarten, mit solchen asynchronen Aktionen umzugehen (schauen Sie sich die andere Antwort an). –

1

@Denys Séguret beantwortet Ihre Frage

nur um zwei Dinge:

1/Es ist eine schlechte Praxis asynchronen Code in einer Schleife

2/Weil Sie von Knoten verwenden zu setzen Ich denke, Es unterstützt ES6 (abhängig von der verwendeten Version). Versuche es!

try { 
    const stats = await Promise.all(list.map((element) => { 
    const path = `${dir}/${element}`; 

    console.log(`Loop files/folders : ${path}`); 

    return fs.stat(path); 
    })); 

    stats.forEach(x => console.log(`fs.stats file path : ${path} : ${stats.isDirectory()}`)); 
} catch (err) { 
// Error handling 
} 
+1

Gute Ergänzungen. Ich denke ein console.log fehlt in der ForEach-Schleife. –

+0

Yup total vergessen es! Danke –

Verwandte Themen