2016-12-20 11 views
1

私は、ディレクトリ内のすべてのフォルダをリストし、そこにいくつのフォルダがあるかを終了リストにリストしたいと思います。このfs.readdir関数の競合条件はどこにありますか?

これは私のコードです:

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. を読みますログ'folders: ' + count
0123多くの場合

これは仕事と私はこの取得ん:競合状態が起こっている

... 
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 

:私はこれを取得のに時々

... 
2016-12-20--09-59-12 
2016-12-20--09-59-13 
2016-12-20--09-59-14 
folders: 86 

を?

答えて

1

fs.statsのコールバックの外側でインクリメントするため、はすべてのfs.statが実行を終了する前にインクリメントが完了できるため、競合状態が発生することがわかりました。

従って私はすべてのfs.statsの補完を追跡するため、およびそれらの私はcountを一覧表示することができますインクリメントが終了した場合にのみ、別の変数(j)が必要です。ここで

は正しいコードです:

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 
関連する問題