promisify: remote-git-tags

33 阅读2分钟

本文参加了由公众号@若川视野发起的每周源码共读活动,点击了解详情一起参与

这是源码共读的第14期,链接:juejin.cn/post/708315…

源码

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

示例:

const tags = await remoteGitTags('https://github.com/facebook/react');

使用 execFile 方法执行 git ls-remote --tags repoUrl 获取所有 tagstags 对应 hash 值存放在 Map 对象中。

归纳

node:child_process

child_process 用来创建子进程

  • 异步方式:spawn exec execFile fork

  • 同步方式:spawnSync execSync execFileSync

spawn

spawn(command[, args][, options]): ChildProcess

command: 要执行的指令
args:    传递参数
options: 配置项

示例:

spawn('ls', ['-l'], {stdio: 'inherit'})

stdio 选项用于配置父进程和子进程之间建立的管道

inherit 方式使得子进程直接使用父进程的 stdio,因此可以看到输出

exec

exec(command[, options][, callback]): ChildProcess

command: 要执行的指令
options: 配置项
callback:回调

示例:

exec('ls', (error, stdout, stderror) => {
  console.log('stdout', stdout)
})

execFile

exec(command[, args][, callback]): ChildProcess

command: 要执行的指令
args:    传递参数
callback:回调

示例:

execFile('ls', ['-l'], (error, stdout, stderror) => {
  console.log('stdout', stdout)
})

fork

fork(modulePath[, options]): ChildProcess

modulePath: 要执行模块路径
options:    配置项

示例:

a.js

function sayHello() {
  console.log('hello')
}

sayHello()
const n = fork('./a.js')
n.on('message', m => {
  console.log('m', m) // hello
})

spawnSync

spawnSync(command[, options]): SpawnSyncReturns

command: 要执行的指令
options: 配置项

示例:

const {stdout} = spawnSync('ls', {encoding: 'utf-8'})
console.log('stdout', stdout)

execSync

execSync(command[, options]): string

command: 要执行的指令
options: 配置项

示例:

const execResult = execSync('ls', {encoding: 'utf-8'})
console.log('execResult', execResult)

execFileSync

execFileSync(command[, args][, options]): string | Buffer

command: 要执行的指令
args:    传递参数
options: 配置项

示例:

const execFileResult = execFileSync('ls', ['-ls'], {encoding: 'utf-8'})
console.log('execFileResult', execFileResult)

spawn / exec / execFile / fork 比较

类型回调/异常执行类型可设置参数
spawn不支持命令不支持
exec支持命令支持
execFile支持可执行文件支持
fork不支持JavaScript 文件不支持

promisify

promisify() 方法可以将基于回调的函数转换为基于 Promise 的函数。

示例:

  1. 基于回调的函数
import fs from 'node:fs'

fs.readFile('./package.json', function callback(err, buf) {
 const obj = JSON.parse(buf.toString('utf8'))
 console.log(obj.name)
})
  1. 基于 Promise 的函数
import {promisify} from 'node:util';
import fs from 'node:fs'

const readFile = util.promisify(fs.readFile)

const buf = await readFile('./package.json')
 ​
const obj = JSON.parse(buf.toString('utf8'))
console.log(obj.name)