这个fs.readdir函数中的竞态条件在哪里?

我想列出一个目录中的所有文件夹,并在结尾列出有多less个文件夹。

这是我的代码:

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

代码应该:

  1. 阅读目录
  2. 目录中每个文件夹的递增count
  3. 当目录读取完成后,logging'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的callback之外递增。

因此,我需要一个单独的variables( 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