Я написал сценарий, который рекурсивно асинхронно изменяет файлы js в каталоге. Он состоит из функции search(dirname), которая ищет в каталоге файлы js, и modify(filename), которая выполняет модификацию.
let totalFilesSearched = 0;
const search = (dir) => {
fs.readdir(dir, (err, list) => {
if (err) return;
list.forEach((filename) => {
const filepath = path.join(dir, filename);
if (filename.endsWith('.js')) {
modify(filepath);
} else if (fs.lstatSync(filepath).isDirectory()) {
search(filepath);
}
})
});
}
const modify = (filename) => {
fs.readFile(filename, 'utf8', (err, data) => {
if (err) console.info(err);
// ... my modification code ...
totalFilesSearched++;
});
}
search(args[0])
console.info(`Total files searched: ${totalFilesSearched}`);
Я хочу распечатать totalFilesSearched в конце моего скрипта, но поскольку мой код асинхронный, он сразу же печатает Total files searched: 0.
Кто-нибудь знает, как бы я дождался конца сценария, чтобы распечатать это? У меня проблема, потому что обе мои функции search() и modify() асинхронны.
Обещание - твой друг
Не уверен, как бы я использовал его здесь, так как мои функции поиска и изменения являются асинхронными
Вот для чего это нужно



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вместо этого используйте Promises, а затем вызовите console.info, когда все будет разрешено. Используйте promisify, чтобы превратить обратные вызовы в обещания:
const { promisify } = require('util');
const readFile = promisify(fs.readFile);
const readDir = util.promisify(fs.readdir);
const search = (dir) => (
readDir(dir).then((list) => (
Promise.all(list.map((filename) => {
const filepath = path.join(dir, filename);
if (filename.endsWith('.js')) {
return modify(filepath); // recursively return the promise
} else if (fs.lstatSync(filepath).isDirectory()) {
return search(filepath); // recursively return the promise
}
}))
))
.catch(err => void 0)
);
const modify = (filename) => (
readFile(filename, 'utf8')
.then((data) => {
// other code
totalFilesSearched++;
}).catch(err => console.info(err))
)
search(args[0])
.then(() => {
console.info(`Total files searched: ${totalFilesSearched}`);
});
Какие ошибки? Правильно ли связаны обещания?
Этого не должно происходить, если вызов readDir не возвращается неявно. Вы уверены, что линия определения search выглядит как const search = (dir) => ( без скобок? (при использовании стрелочной функции, если будет возвращен первый оператор, используйте круглые скобки или ничего вместо скобок {} с оператором return)
изменил его, но тут же вызывается .then()
Какой then? Вы имеете в виду, что list не определен?
Нет, последний .then(), сразу же распечатывается "Всего файлов ..."
Позвольте нам продолжить обсуждение в чате.
Кстати. На мой вопрос было решение попроще. Просто используйте process.on('exit', callback_function_to_execute_at_end)
Самостоятельный ответ:
Просто используйте process.on('exit', callback_function_to_execute_at_end)
Он встроен в узел, ваш обратный вызов будет выполнен прямо перед завершением процесса.
Используйте обещание