fs.readdir 函数中的竞争条件在哪里?
Where is the race condition in this fs.readdir function?
我想列出目录中的所有文件夹,并在末尾列出有多少个文件夹。
这是我的代码:
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
竞争条件发生在哪里?
我意识到竞争条件的发生是因为 i
可以在所有 fs.stat
完成执行之前完成递增,因为它在 fs.stats
的回调之外递增。
因此我需要一个单独的变量(j
)来跟踪所有fs.stats
的完成,并且只有当那些完成递增时才能我列出 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);
}
});
}
});
现在输出一致:
...
2016-12-20--09-59-13
2016-12-20--09-59-11
2016-12-20--09-59-14
folders: 86
我想列出目录中的所有文件夹,并在末尾列出有多少个文件夹。
这是我的代码:
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
竞争条件发生在哪里?
我意识到竞争条件的发生是因为 i
可以在所有 fs.stat
完成执行之前完成递增,因为它在 fs.stats
的回调之外递增。
因此我需要一个单独的变量(j
)来跟踪所有fs.stats
的完成,并且只有当那些完成递增时才能我列出 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);
}
});
}
});
现在输出一致:
...
2016-12-20--09-59-13
2016-12-20--09-59-11
2016-12-20--09-59-14
folders: 86