NodeJS fs.stat在一个循环内

我有什么我会叫一个奇怪的问题..我想这是如何节点asynchronous工作,但我不知道如何解决它..

我有以下代码:

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

这给出了以下输出:

 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 

从代码中可以看到,首先给出循环中的pathstring的输出。 然后,在同一个循环中,我为导演内部的每个path(元素)做一个统计。 这里发生什么是当我在fs.statcallback中使用pathvariables,这是指最后一个文件“阿伦达尔”,而不是循环中的每个单独的项目。 isDirectory bool实际上是根据文件和目录列表正确的,但是对于我来说,使用给定的isDirectory bool来获取正确的path也是非常重要的。

如何解决这个问题?

这里的问题是你不要在正确的范围内声明pathvariables。

改变你的代码

 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的同步函数(以便将调用顺序保存在日志中)即可获得更清晰的日志。

@DenysSéguret回答了你的问题

只需添加两件事:

1 /将asynchronous代码放在一个循环内是不好的做法

2 /因为你使用节点,我猜它支持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 }