在节点脚本结束时运行命令行?

3

我编写了一个脚本,可以递归地异步修改目录中的JavaScript文件。它由一个名为search(dirname)的函数和一个名为modify(filename)的函数组成。其中,search(dirname)函数用于搜索目录中的JavaScript文件,而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.log(err);
        // ... my modification code ...
        totalFilesSearched++;
    });
}

search(args[0])
console.log(`Total files searched: ${totalFilesSearched}`);

我想在脚本结束时打印出totalFilesSearched,但由于我的代码是异步的,它会立即打印Total files searched: 0
有人知道我怎样才能等到脚本即将结束时再打印出来吗?我遇到了麻烦,因为我的search()modify()函数都是异步的。

使用 Promise。 - Sean F
Promise 是你的朋友。 - Sean F
不确定如何在这里使用它,因为我的搜索和修改函数都是异步的。 - MarksCode
这就是它的用途。 - Sean F
2个回答

2

使用Promise代替回调函数,等待所有操作完成后再调用console.log。可以使用promisify将回调函数转换为Promise:

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.log(err))
)

search(args[0])
  .then(() => {
    console.log(`Total files searched: ${totalFilesSearched}`);
  });

除非readDir调用没有被隐式返回,否则不应该发生这种情况。你确定search定义行看起来像const search = (dir) => (,没有括号吗?(如果使用箭头函数,如果第一个语句将被返回,则使用括号或不使用{}括号与return语句) - CertainPerformance
更改了它,但随后立即调用了.then() - MarksCode
哪个“then”?你是说“list”未定义? - CertainPerformance
让我们在聊天中继续这个讨论 - CertainPerformance
顺便提一下,对于我的问题有一个更简单的解决方案。只需使用 process.on('exit', callback_function_to_execute_at_end) 即可。 - MarksCode
显示剩余2条评论

0

自我回答:

只需使用 process.on('exit', callback_function_to_execute_at_end)

它内置于节点中,您的回调将在进程退出之前立即执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接