util 是Node.js内部提供的很多实用或者工具类型的API,方便我们快速开发。
由于API比较多 我们介绍一些常用的API
util.promisify
我们之前讲过Node.js 大部分API 都是遵循 回调函数的模式去编写的。
例如我们之前讲的exec
获取Node版本
js
import { exec } from 'node:child_process'
exec('node -v', (err,stdout)=>{
if(err){
return err
}
console.log(stdout)
})
以上就是常规写法
我们使用util的promisify
改为promise 风格 Promiseify 接受 original
一个函数体
js
import { exec } from 'node:child_process'
import util from 'node:util'
const execPromise = util.promisify(exec)
execPromise('node -v').then(res=>{
console.log(res,'res')
}).catch(err=>{
console.log(err,'err')
})
剖析promiseify如何实现的
- 第一步Promiseify是返回一个新的函数
js
const promiseify = () => {
return () => {
}
}
- promiseify接受一个函数,并且在返回的函数才接受真正的参数,然后返回一个promise
js
const promiseify = (original) => {
return (...args) => {
return new Promise((resolve,reject)=>{
})
}
}
- 调用真正的函数,将参数透传给original,如果失败了就reject,如果成功了,就返回resolve,如果有多个返回一个对象。
js
const promiseify = (original) => {
return (...args) => {
return new Promise((resolve, reject) => {
original(...args, (err, ...values) => {
if (err) {
return reject(err)
}
if (values && values.length > 1) {
let obj = {}
console.log(values)
for (let key in values) {
obj[key] = values[key]
}
resolve(obj)
} else {
resolve(values[0])
}
})
})
}
}
这样可以大致实现但是拿不到values 的key 因为 nodejs内部 没有对我们开放 这个Symbol kCustomPromisifyArgsSymbol
所以输出的结果是 { '0': 'v18.16.0\n', '1': '' }
正常应该是 { stdout: 'v18.16.0\n', stderr: '' }
但是我们拿不到key,只能大概实现一下。
util.callbackify
这个API 正好是 反过来的,将promise类型的API变成 回调函数。
js
import util from 'node:util'
const fn = (type) => {
if(type == 1){
return Promise.resolve('test')
}
return Promise.reject('error')
}
const callback = util.callbackify(fn)
callback(1222,(err,val)=>{
console.log(err,val)
})
剖析callbackify
js
const callbackify = (fn) => {
return (...args) => {
let callback = args.pop()
fn(...args).then(res => {
callback(null, res)
}).catch(err => {
callback(err)
})
}
}
这个比较简单,因为考虑多个参数的情况,但是回调函数肯定在最后一个,所以使用pop把他取出来。
util.format
%s
:String
将用于转换除BigInt
、Object
和-0
之外的所有值。BigInt
值将用n
表示,没有用户定义的toString
函数的对象使用具有选项{ depth: 0, colors: false, compact: 3 }
的util.inspect()
进行检查。%d
:Number
将用于转换除BigInt
和Symbol
之外的所有值。%i
:parseInt(value, 10)
用于除BigInt
和Symbol
之外的所有值。%f
:parseFloat(value)
用于除Symbol
之外的所有值。%j
: JSON。 如果参数包含循环引用,则替换为字符串'[Circular]'
。%o
:Object
. 具有通用 JavaScript 对象格式的对象的字符串表示形式。 类似于具有选项{ showHidden: true, showProxy: true }
的util.inspect()
。 这将显示完整的对象,包括不可枚举的属性和代理。%O
:Object
. 具有通用 JavaScript 对象格式的对象的字符串表示形式。 类似于没有选项的util.inspect()
。 这将显示完整的对象,但不包括不可枚举的属性和代理。%c
:CSS
. 此说明符被忽略,将跳过任何传入的 CSS。%%
: 单个百分号 ('%'
)。 这不消费参数。
语法 跟 C 语言的 printf
一样的
js
util.format(format, [args])
例子 格式化一个字符串
js
util.format('%s-----%s %s/%s','foo','bar','xm','zs')
//foo-----bar xm/zs 可以返回指定的格式
如果不传入格式化参数 就按空格分开
js
util.format(1,2,3)
//1 2 3