2016-12-20 4 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. Increment count для каждой папки в каталоге
  3. Когда чтение каталога завершена, лог '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 

Где состояние гонки происходит?

ответ

1

Я понял, что состояние гонки происходит потому, что 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 
Смежные вопросы