NodeJS

2017-08-24 7 views
2

私は奇妙な問題を呼ぶようなものを持っている..私は.. it'sは、ノードが非同期的にどのように機能するかに関係しますが、私はそれを解決する方法を見つけ出すことができないと思いますNodeJS

私は、次のコードを持っている:あなたが最初に私はちょうどループ内でパス文字列の出力が得られ、コードから見ることができるように

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 

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); 
}); 

} 

これは、次の出力が得られます。そして、この同じループの中で、ディレクターの中のすべてのパス(要素)についてstatを実行します。ここでは、fs.statコールバックでpath変数を使用すると、ループの個々の項目ではなく、最後のファイル "Arendal"が参照されます。 isDirectory boolは実際にはファイルとディレクトリのリストに従って正しくありますが、指定されたisDirectory boolで正しいパスを取得することも重要です。

これを解決するにはどうすればよいですか?

答えて

4

ここでの問題は、path変数を正しいスコープに宣言していないことです。

はそれだけでコマンドラインユーティリティだと仮定すると、リストのこの種の

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); 

にあなたのコードを変更

、あなたは、単にfsの同期機能を使用することによってより明確にログを取得する可能性があります(そのように呼び出しの順序ログに保存されます)。

+0

完璧な、私の問題を解決しました。実際にはコマンドラインツールだけではありません。非常に大きなファイル構造/多数のファイルに対して、AWSに「スマート」な同期ツールを作成しようとしています。私は非同期私は有益だと思います。 – chranmat

+0

@chranmat次に、非同期アクションを扱うための約束と非同期/待機を見てみることをお勧めします(他の回答を見てください)。 –

1

@DenysSéguretちょうど二つのことを追加し、あなたの質問

に答え:あなたはノードの使用私は推測しているので

1 /ループ

2 /内asynchonousコードを配置する悪い習慣ですES6をサポートしています(使用しているバージョンによって異なります)。試してみる!

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

良い補足物。私は、forEachループにconsole.logがないと思います。 –

+0

うん、それは完全に忘れてしまった!どうも –