Это имеет отношение к обратным вызовам.В
fs.readdir('./' + dirname, function(err, res) {
if (err) throw err;
result[dirname] = res;
// #2
});
переданная функция является обратным вызовом, который выполняется, когда каталог полностью прочитан.Поскольку он асинхронный, fs.readdir () возвращает до , когда функция фактически выполняется.
Таким образом, в основном, после того, как ваш forEach завершает работу, у вас есть 3 функции, ожидающие выполнения в качестве обратных вызовов (по одной для каждого каталога).Код не ждет, пока произойдут обратные вызовы, прежде чем продолжить выполнение, поэтому, если # 1 достигнут до того, как каталоги прочитаны, он запишет ваш объект результата перед выполнением обратных вызовов и соответствующим образом его изменит.
Вы можетеиспользуйте вместо этого fs.readdirSync, но ТОЛЬКО ЕСЛИ для вашего приложения было бы неплохо, если бы этот код кратковременно блокировался / нет опасности, что этот код заблокируется на неопределенный срок и остановит вашу программу.Если вам нужно, чтобы он оставался асинхронным, посмотрите на ответ Дж.