【源码共读】第14期 | 通过remote-git-tags学会promisify

1. 前言

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;
}

运行步骤:

  1. 使用child_process.exec()执行命令,用promisify包裹,返回promsie
  2. 遍历版本和Hash放到一个Map对象中,使用两次替换,最终获得版本

执行命令的结果"bac3bd8ecf9beb7b1d8dfb596cb89a7fd898936b\trefs/tags/v1.0.0\ndeb487bbb4fa1a22bbe6462aa527b2bcf0248f02\trefs/tags/v1.0.0^{}\n"

5. 总结

最后总结一波:

  1. remote-git-tags使用了child_process.execFile方法来执行命令,并通过promisify将其转换为Promise形式。它接受一个仓库URL作为参数,并返回一个包含tag信息的Map对象。

  2. 通过执行命令并遍历结果,我们将版本和对应的hash值存储在一个Map对象中,并最终获得了版本信息。

如有错误,请指正O^O!

相关推荐
YAY_tyy2 小时前
Vue3 + Three.js 实战:自定义 3D 模型加载与交互全流程
前端·javascript·vue.js·threejs
星河耀银海2 小时前
3D效果:HTML5 WebGL结合AI实现智能3D场景渲染
前端·人工智能·深度学习·3d·html5·webgl
美狐美颜sdk7 小时前
从人脸关键点到动态贴图:面具特效在美颜SDK中的实现原理
前端·图像处理·人工智能·直播美颜sdk·美颜api
我命由我123457 小时前
React Router 6 - 编程式路由导航、useInRouterContext、useNavigationType
前端·javascript·react.js·前端框架·html·ecmascript·js
威联通网络存储7 小时前
告别掉帧与素材损毁:威联通 QuTS hero 如何重塑影视后期协同工作流
前端·网络·人工智能·python
anOnion7 小时前
构建无障碍组件之Tabs Pattern
前端·html·交互设计
一招定胜负8 小时前
课堂教学质量综合评分系统
java·linux·前端
2301_780669868 小时前
前端logo替换开发
前端·vue.js
启山智软9 小时前
【启山智软智能商城系统技术架构剖析】
java·前端·架构
我命由我123459 小时前
React Router 6 - 嵌套路由、路由传递参数
前端·javascript·react.js·前端框架·html·ecmascript·js