我越来越多地了解节点,我遇到的最大问题是如何确定异步函数的工作原理。
fs.readdir(base, function (err, files) {
if (!files.length) {
console.log('No files');
}
for (var i in files) {
fs.stat(files[i], function (err, stats) {
if (stats.isDirectory()) {
console.log(files[i]);
console.log('FOLDER');
} else {
console.log(files[i]);
console.log('FILE')
}
})
}
});
base
是一个包含两个子文件夹的文件夹,以及一个.DS_Store文件。命令行的输出为:
.DS_Store
FILE
/dir/to/file/index.js:115
if (stats.isDirectory()) {
^
TypeError: Cannot read property 'isDirectory' of undefined
我现在的基本理解是存在这个问题,因为它全部是异步发生的 - 我最好的猜测是readdir
回调不会'等待'fs.stat
回调完成?我可能完全误解了它(实际上,从这个基础理解中学习的任何好文件都会有所帮助)。
我的下一个想法就像承诺一样?他们似乎解决了异步的许多问题,这将是我学习的下一个飞跃。
这是'回调地狱'吗?承诺是修复吗?有没有不同的方法来做到这一点?
答案 0 :(得分:0)
这里可能存在一些问题,具体取决于您的其余代码。一个是fs.stat将路径作为第一个参数而不是文件名。如果您将函数调用更改为可能有用的fs.stat(base + '/' + files[i], function (err, stats)
。但我不确定你的例子中base
是什么。
其次,您应该在循环中使用ES6 let
而不是var
。异步函数将放在调用堆栈上,并在完成后按顺序处理。但是,到那时循环将一直运行,变量i
将等于其在最后一次迭代中的值。另一方面,使用let
定义的变量在范围上限于块,这意味着每个函数(因为它们位于不同的块中)将具有正确的i
值。
尝试测试以下两个不同的版本,首先使用for (var i in files)
,然后使用for (let i in files)
,您将看到我的意思。
for (var i in files) {
fs.stat(files[i], function (err, stats) {
if (stats.isDirectory()) {
console.log(files[i]);
console.log('FOLDER');
console.log(i);
} else {
console.log(files[i]);
console.log('FILE')
console.log(i);
}
})
}
此外,正如您对问题的评论中所建议的,我建议您进行正确的错误处理。