我想列出目录中的所有文件夹,并在结尾列表中列出有多少个文件夹。
这是我的代码:
fs.readdir(dir, (err, folders) => {
if (err) return console.log(err);
let count = 0;
for (let i = 0; i < folders.length; i++) {
let folder = folders[i];
fs.stat(dir + '/' + folder, (err, stats) => {
if (err) return console.log(err);
if (stats.isDirectory()) {
console.log(folder);
count++;
}
if (i >= (folders.length - 1)) {
console.log('folders: ' + count);
}
});
}
});
代码应该:
count
'folders: ' + count
在大多数情况下,这确实有效,我明白了:
...
2016-12-20--09-59-12
2016-12-20--09-59-13
2016-12-20--09-59-14
folders: 86
有时虽然我明白了:
...
2016-12-20--09-59-12
2016-12-20--09-59-11
2016-12-20--09-59-14
folders: 85
2016-12-20--09-59-13
竞争条件发生在哪里?
答案 0 :(得分:1)
我意识到竞争条件的发生是因为i
可以在所有fs.stat
完成执行之前完成递增,因为它会在fs.stats
的回调之外递增。
因此我需要一个单独的变量(j
)来跟踪所有fs.stats
的完成情况,并且只有当那些完成递增时才能列出{{1} }}
这是正确的代码:
count
现在输出始终如一:
fs.readdir(dir, (err, folders) => {
if (err) return console.log(err);
let count = 0,
j = 0; // this bad boy!
for (let i = 0; i < folders.length; i++) {
let folder = folders[i];
fs.stat(dir + '/' + folder, (err, stats) => {
if (err) return console.log(err);
j++; // j, unlike i, only gets incremented *inside* the async function
if (stats.isDirectory()) {
console.log(folder);
count++;
}
if (j >= folders.length) { // check j, not i
console.log('folders: ' + count);
}
});
}
});