1. 前言
-
本文参加了由 公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
-
这是源码共读的第14期,链接:promisify
2. remote-git-tags
remote-git-tags
是用来获取远程仓库tag的库。 在学习这个之前,先来认识下promisify
是什么?
3. promisify
promisify是一个可以将回调函数转换为Promise形式函数的工具。回调函数是最原始的异步处理方案,但使用它容易引发一些问题,如回调地狱和对异常错误的捕获不够方便等。
例如:现在使用node读取文件
回调写法
js
fs.readFile("test.txt", function (err, data) {
if (!err) {
console.log('callback',data.toString());
} else {
console.log(err);
}
});
promise写法
js
const promiseRead = () => {
return new Promise((resolve, reject) => {
fs.readFile("test.txt", function (err, data) {
if (!err) {
resolve(data.toString());
} else {
reject(err);
}
});
});
};
promisify写法
js
import { promisify } from "node:util";
const fn = promisify(fs.readFile);
fn("test.txt").then((res) => {
console.log('promisify', res.toString());
});
自实现promisify写法
js
const selfPromisify = (original) => {
return (...args) => {
return new Promise((resolve, reject) => {
args.push((err, ...values) => {
if (err) {
return reject(err);
}
resolve(values);
});
Reflect.apply(original, this, args);
});
};
};
const selfFn = promisify(fs.readFile);
const res = await selfFn("test.txt");
结果如下:
4. remote-git-tags源码调试
js
import {promisify} from 'node:util';
import childProcess from 'node:child_process';
const execFile = promisify(childProcess.execFile);
export default async function remoteGitTags(repoUrl) {
const {stdout} = await execFile('git', ['ls-remote', '--tags', repoUrl]);
const tags = new Map();
for (const line of stdout.trim().split('\n')) {
const [hash, tagReference] = line.split('\t');
const tagName = tagReference.replace(/^refs\/tags\//, '').replace(/\^{}$/, '');
tags.set(tagName, hash);
}
return tags;
}
运行步骤:
- 使用
child_process.exec()
执行命令,用promisify包裹,返回promsie - 遍历版本和
Hash
放到一个Map
对象中,使用两次替换,最终获得版本
执行命令的结果"bac3bd8ecf9beb7b1d8dfb596cb89a7fd898936b\trefs/tags/v1.0.0\ndeb487bbb4fa1a22bbe6462aa527b2bcf0248f02\trefs/tags/v1.0.0^{}\n"
5. 总结
最后总结一波:
-
remote-git-tags
使用了child_process.execFile
方法来执行命令,并通过promisify
将其转换为Promise形式。它接受一个仓库URL作为参数,并返回一个包含tag信息的Map对象。 -
通过执行命令并遍历结果,我们将版本和对应的hash值存储在一个Map对象中,并最终获得了版本信息。
如有错误,请指正O^O!