javascript - 我在 Node JS 中检索 Git 标签信息的方法很慢,如何加快速度?
问题描述
我正在创建一个 Node JS 脚本,该脚本需要从存储库中获取所有 Git 标签,以及创建标签的消息和日期,然后将它们保存为 JSON 文件中的条目。例如:
[{
"tag": "v1.1.0",
"message": "Add navigation",
"date": "Tue Oct 4 10:19:12 2018 +0100"
}, {
"tag": "v1.1.1",
"message": "Fix issue with spacing in the navigation",
"date": "Tue Oct 9 12:13:16 2018 +0100"
}]
我已经弄清楚了如何做到这一点,使用一些 Node 模块来访问标签,然后执行一些 Git 命令来从每个标签中获取我需要的所有信息。这是使用shelljs完成的。
我遇到的问题是这非常慢。运行gitTag.all((tags) = {})
(使用git-tag)很快,因为它只是拉入标签名称。但是,为了获取消息和日期,我在一个循环中为每个标签运行了两个单独的命令:
let msg = shell.exec(`git for-each-ref refs/tags/${tag} --format='%(subject)'`, {silent:true}).stdout;
let date = shell.exec(`git for-each-ref refs/tags/${tag} --format='%(authordate)'`, {silent:true}).stdout;
无论如何,这两个命令都有点慢,但是每次为每个标签名称运行它们都需要很长时间。
我有没有更快的方法来做到这一点?
请记住,我正在同步运行它,因为另一个 Node 脚本将读取这个 JSON 文件,它可能会导致竞争条件。然而,如果他们也可以解决这个问题,任何异步想法都是受欢迎的。
请在下面查看我的完整代码:
const gitTag = require('git-tag')({
localOnly: true,
dir: '.git'
});
const fs = require('fs-extra');
const shell = require('shelljs');
let tagsAllData = [];
let formatString = (string) => {
return string.replace(/^'/, '').replace(/'\n+$/, '');
}
// Fetch all git tags
gitTag.all((tags) => {
tags.forEach(tag => {
// Collect the tag message and date values
let msg = shell.exec(`git for-each-ref refs/tags/${tag} --format='%(subject)'`, {silent:true}).stdout;
let date = shell.exec(`git for-each-ref refs/tags/${tag} --format='%(authordate)'`, {silent:true}).stdout;
// Create array of tag objects
tagsAllData.push({
'tag': tag,
'message': formatString(msg),
'date': formatString(date)
});
});
// Write the tag data as a JSON file
let tagsJSON = JSON.parse(JSON.stringify(tagsAllData));
fs.writeJSONSync('src/data/tags.json', tagsJSON);
});
解决方案
在其他答案的基础上,我还会考虑使整个方法更加异步。foreach
是阻塞的,将取决于每个呼叫的单独结果。
相反,我会使用本机 API 并从中创建一个 Promise(如此处所述)。
你可以使用Promise.all来聚合结果。这是一个简化的例子
const dateQueries = [];
const msgQueries = [];
tags.forEach(tag => {
const dateQuery = exec(`git for-each-ref refs/tags/${tag} --format='%(subject)'`);
const msgQuery = exec(`git for-each-ref refs/tags/${tag} --format='%(authordate)'`);
dateQueries.push(dateQuery);
msgQueries.push(msgQuery);
});
const msgResults = await Promise.all(msgQueries);
const dateResults = await Promise.all(dateQueries);
但是,AH 的答案是性能更高的答案,因为它优化了查询本身。
推荐阅读
- azure - 如何使用 Azure Policy 限制对网络安全组的任何/任何 RDP 和 SSH 访问?
- java - 如何使用 AdoptOpenJDK 运行 PhpStorm 9.3
- intellij-idea - 自动将 switch 语句转换为 if-else (Dart)
- swift - Swift Pusher 示例什么都不做
- c++ - 输出字符串末尾的空白不与字符串一起打印,而是与它之后的下一个打印行一起打印
- angular - 对于每个和 http 获取角度
- intel - 了解英特尔内部指南中的代码示例
- c# - EF Core:如何生成 C# 代码以填充来自 SQL Server 的单元测试数据的 dbcontext
- javascript - 更改对象数组后,离子选择选项不会刷新
- qt - 如何在 Qt 中部署 openvino-opencv