Выполнить строку в конце скрипта узла?

Я написал сценарий, который рекурсивно асинхронно изменяет файлы 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() асинхронны.

Используйте обещание

Sean F 27.05.2018 08:15

Обещание - твой друг

Sean F 27.05.2018 08:16

Не уверен, как бы я использовал его здесь, так как мои функции поиска и изменения являются асинхронными

MarksCode 27.05.2018 08:16

Вот для чего это нужно

Sean F 27.05.2018 08:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
4
40
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вместо этого используйте 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}`);
  });

Какие ошибки? Правильно ли связаны обещания?

CertainPerformance 27.05.2018 09:12

Этого не должно происходить, если вызов readDir не возвращается неявно. Вы уверены, что линия определения search выглядит как const search = (dir) => ( без скобок? (при использовании стрелочной функции, если будет возвращен первый оператор, используйте круглые скобки или ничего вместо скобок {} с оператором return)

CertainPerformance 27.05.2018 09:23

изменил его, но тут же вызывается .then()

MarksCode 27.05.2018 09:26

Какой then? Вы имеете в виду, что list не определен?

CertainPerformance 27.05.2018 09:30

Нет, последний .then(), сразу же распечатывается "Всего файлов ..."

MarksCode 27.05.2018 09:33

Позвольте нам продолжить обсуждение в чате.

CertainPerformance 27.05.2018 09:45

Кстати. На мой вопрос было решение попроще. Просто используйте process.on('exit', callback_function_to_execute_at_end)

MarksCode 28.05.2018 09:20

Самостоятельный ответ:

Просто используйте process.on('exit', callback_function_to_execute_at_end)

Он встроен в узел, ваш обратный вызов будет выполнен прямо перед завершением процесса.

Другие вопросы по теме