node.js中Util模块作用教程示例详解

目录
  • 从类型判断说起
    • 严格相等
  • Error First & Promise
  • 调试与输出

从类型判断说起

在 JavaScript 中,进行变量的类型校验是一个非常令人头疼的事,如果只是简单的使用 typeof 会到各种各样的问题。

举几个简单的:

console.log(typeof null) // 'object'
console.log(typeof new Array) // 'object'
console.log(typeof new String) // 'object'

后来,大家发现可以使用 Object.prototype.toString() 方法来进行变量类型的判断。

const getTypeString = obj => Object.prototype.toString.call(obj)

getTypeString(null) // '[object Null]'
getTypeString('string') //'[object String]'
getTypeString(new String) //'[object String]'

对 toString() 方法进行代理,可以得到一个类型字符串,我们就可以在这个字符串上面搞事情。

const getTypeString = obj => {
  return Object.prototype.toString.call(obj)
}
const isType = type => {
  return obj => {
    return getTypeString(obj) === `[object ${type}]`
  }
}
const isArray = isType('Array') // 该方法一般通过 Array.isArray 代替
const isNull = isType('Null')
const isObject = isType('Object')
const isRegExp = isType('RegExp')
const isFunction = isType('Function')
const isAsyncFunction = isType('AsyncFunction')
isNull(null) // true
isObject({}) // true
isRegExp(/\w/) // true
isFunction(() => {}) // true
isAsyncFunction(async () => {}) // true

But,在 Node.js 中,内部其实是有一组用来判断变量类型的 api 的。而且功能异常丰富,除了基础类型的判断,还支持判断 Promise 对象、Date 对象、各种ArrayBuffer。

const types = require('util/types')
types.isDate(new Date) // true
types.isPromise(new Promise(() => {})) // true
types.isArrayBuffer(new ArrayBuffer(16)) // true

严格相等

在 JavaScript 中,对象、数组等变量在判断相等的过程中,如果用 === 通常只会判断这两个变量是否指向同一内存地址。如果想判断对象的键对应的所有值是否相等,需要对两个对象进行遍历。在 util 中,也提供了一个方法可以用来判断两个对象是否严格相等:util.isDeepStrictEqual(val1, val2)

const util = require('util')
const val1 = { name: 'shenfq' }
const val2 = { name: 'shenfq' }
console.log('val1 === val2', val1 === val2) // false
console.log('isDeepStrictEqual', util.isDeepStrictEqual(val1, val2)) // true

该方法同样可以用来判断数组,是否严格相等:

const util = require('util')
const arr1 = [1, 3, 5]
const arr2 = [1, 3, 5]
console.log('arr1 === arr2', arr1 === arr2) // false
console.log('isDeepStrictEqual', util.isDeepStrictEqual(arr1, arr2)) // true

Error First & Promise

早期的 Node API 都是 Error First 风格的,也就是所有的异步函数都会接受一个回调函数,该回调的一个参数为 error 对象,如果正常返回 error 对象为 null,后面的参数为成功响应的结果。

// 下面是一个读取文件的示例
const fs = require('fs')
fs.readFile('nginx.log', (error, data) => {
  if (error) {
    // 读取文件失败
    console.error(error)
    return
  }
  // 读取文件成功,打印结果
  console.log(data)
})

在 Node 8 发布的时候,新增了一个 promisify 接口,用于将 Error First 风格的 API 转为 Promise API。

const fs = require('fs')
const util = require('util')
const readFile = util.promisify(fs.readFile)
readFile('./2021-11-11.log', { encoding: 'utf-8' })
  .then(text => console.log(text))
    .catch(error => console.error(error))

不过,后来也有很多人觉得这些原生 API 支持 Promise 的方式太过繁琐,每个 API 都需要单独的包装一层 promisify 方法。在 Node 10 发布的时候,原生模块都新增了一个 .promises 属性,该属性下的所有 API 都 Promise 风格的。

const fs = require('fs').promises
fs.readFile('./2021-11-11.log', { encoding: 'utf-8' })
  .then(text => console.log(text))
    .catch(error => console.error(error))

注意:Node 14 后,promises API 又新增了一种引入方式,通过修改包名的方式引入。

const fs = require('fs/promises')
fs.readFile('./2021-11-11.log', { encoding: 'utf-8' })
  .then(text => console.log(text))
    .catch(error => console.error(error))

除了将 Error First 风格的 API 转为 Promise API,util 中还提供 callbackify 方法,用于将 async 函数转换为 Error First 风格的函数。

下面通过 callbackify 将 promise 化的 fs 还原为 Error First 风格的函数。

const fs = require('fs/promises')
const util = require('util')
const readFile = util.callbackify(fs.readFile)
readFile('./2021-11-12.log', { encoding: 'utf-8' }, (error, text) => {
  if (error) {
    console.error(error)
    return
  }
  console.log(text)
})

调试与输出

如果有开发过 Node 服务,应该都用过 debug 模块,通过该模块可以在控制台看到更加明晰的调试信息。

const debug = require('debug')
const log = debug('app')
const user = { name: 'shenfq' }
log('当前用户: %o', user)

其实,通过 util.debug 也能实现类似的效果:

const debug = require('debug')
const log = debug('app')
const user = { name: 'shenfq' }
log('当前用户: %o', user)

只是在启动时,需要将 DEBUG 环境变量替换为 NODE_DEBUG

如果你有认真看上面的代码,应该会发现,在 log('当前用户: %o', user) 方法前面的字符串中,有一个 %o 占位符,表示这个地方将会填充一个对象(object)。这与 C 语言或 python 中的,printf 类似。同样,在 util 模块中,直接提供了格式化的方法:util.format

const { format } = require('util')
console.log(
  format('当前用户: %o', {
    name: 'shenfq', age: 25
  })
)

除了 %o 占位符,不同的数据类型应使用不同的占位符。

占位符 类型
%s 字符串
%d 数字(包括整数和浮点数)
%i 整数
%f 浮点数
%j JSON
%o Object

JavaScript 中的对象是一个很复杂的东西,除了直接使用 util.format 外加 %o 占位符的方式格式化对象,util 中还提供了一个叫做 inspect 方法来进行对象格式化。

const { inspect } = require('util')
const user = {
  age: 25,
  name: 'shenfq',
  work: {
    name: 'coding',
    seniority: 5
  }
}
console.log(inspect(user))

这么看 inspect 好像什么都没做,但是 inspect 方法还有第二个参数,用来进行格式化时的一些个性化配置。

depth: number:控制显示层级;

sorted: boolean|Function: 是否按照key的编码值进行排序;

compact: boolean:是否进行单行显示;

当然上面只是一部分配置,更详细的配置可查阅 node 文档,下面我们写几个案例:

所有的属性都换行显示:

inspect(user, {
    compact: false
})

只格式化对象第一层的值:

inspect(user, {
  depth: 0,
    compact: false
})

按照key值的编码倒序输出:

inspect(user, {
    compact: false,
  sorted: (a, b) => a < b ? 1 : -1
})

以上就是node.js中Util模块教程示例详解的详细内容,更多关于node.js中Util模块的资料请关注我们其它相关文章!

(0)

相关推荐

  • nodejs基础之常用工具模块util用法分析

    本文实例讲述了nodejs基础之常用工具模块util用法.分享给大家供大家参考,具体如下: util是nodejs的核心模块,提供常用函数的集合,用户弥补核心javascript的功能过于精简的不足 util.inherits 是一个实现对象间原型继承的函数 javascript的面向对象特性是基于原型的,与常见的基于类的不同.javascript没有提供对象继承的语言级别特性,而是通过原型复制来实现的. 示例: var util = require('util'); function Fath

  • 详解nodejs内置模块

    概述 nodejs内置模块指的是除默认提供的语法之外,提供的美容,无需下载,直接引入,引入只写名称即可. nodejs内置模块: 1.path模块  用于处理文件路径. path.normalize(路径解析,得到规范路径): path.join(路径合并): path.resolve(获取绝对路径): path.relative(获取相对路径). ...... 2.until模块  弥补js功能不足,新增API. util.format(格式化输出字符串); util.isArray(检查是否

  • 详解NodeJS模块化

    目录 一.前言 二.正文 2.1.什么是模块 2.2.Resolving 2.3.require.resolve 2.4.模块间的父子依赖关系 2.5.exports, module.exports 2.6.模块循环依赖 2.7..json和.node 2.8.Wrapping 2.9.Cache 三.总结 一.前言 我们知道,Node.js是基于CommonJS规范进行模块化管理的,模块化是面对复杂的业务场景不可或缺的工具,或许你经常使用它,但却从没有系统的了解过,所以今天我们来聊一聊Node

  • Node.js常用工具之util模块

    前言 util是一个Node.js的核心工具模块,提供常用的函数,用于弥补核心JavaScript提供的函数过于精简的问题.下面话不多说,一起来看看详细的介绍,文中介绍的非常详细,对大家具有一定的参考价值. util.inherits uitl.inherits(constructor,superConstructor)是一个实现对象间圆形继承的函数.JavaScript的面相对象特性是基于原型的,与常见的基于类的不同.JavaScript没有提供对象继承的语言级别特性,而是通过原型复制来实现的

  • Node.js API详解之 util模块用法实例分析

    本文实例讲述了Node.js API详解之 util模块用法.分享给大家供大家参考,具体如下: Node.js API详解之 util util 模块主要用于支持 Node.js 内部 API 的需求.提供了大部分实用工具. 通过 const util = require('util'); 的方式引用util模块 util.callbackify(original) 说明: original:传递一个 async 函数,或者是一个返回Promise的异步函数. callbackify会返回一个方

  • node.js中Util模块作用教程示例详解

    目录 从类型判断说起 严格相等 Error First & Promise 调试与输出 从类型判断说起 在 JavaScript 中,进行变量的类型校验是一个非常令人头疼的事,如果只是简单的使用 typeof 会到各种各样的问题. 举几个简单的: console.log(typeof null) // 'object' console.log(typeof new Array) // 'object' console.log(typeof new String) // 'object' 后来,大

  • windows系统下node.js环境配置与安装教程图文详解(详细版)

    国内目前关注最高,维护最好的一个关于nodejs的网站应该是http://www.cnodejs.org/ windows系统下简单nodejs环境配置. 第一步:下载安装文件 下载地址:官网https://nodejs.org/en/download/ 这里用的是 第二步:安装nodejs 下载完成之后,双击 node-v6.9.1-x64.msi,开始安装nodejs,默认是安装在C:\Program Files\nodejs下面 第三步:安装相关环境 打开C:\Program Files\

  • Node.js中参数传递的两种方式详解

    目录 参数传递方式 GET方式 POST方式 动态网页 参数传递方式 在Node.js中,参数传递常见的共两种方式: GET方式:通过地址栏键=值的方式进行传递. POST方式:通过表单的方式传递请求数据. GET方式 GET方式通常是在请求地址中以[?参数1=值1&参数2=值2]的格式进行传递,在Node.js中可以通过获取url然后进行获取参数,如下所示: //1.引入http模块 var http = require('http'); //2.创建服务 var server = http.

  • node.js中grunt和gulp的区别详解

    node.js中grunt和gulp的区别详解 自nodeJS登上前端舞台,自动化构建变得越来越流行.目前最流行的当属grunt和gulp,这两个光看名字挺像,功能也差不多,不过gulp能在grunt这位大哥如日中天的境况下开辟出自己的一片天地,有着她独到的优点. 易用 Gulp相比Grunt更简洁,而且遵循代码优于配置策略,维护Gulp更像是写代码. 高效 Gulp相比Grunt更有设计感,核心设计基于Unix流的概念,通过管道连接,不需要写中间文件. 高质量 Gulp的每个插件只完成一个功能

  • 对node.js中render和send的用法详解

    大多数情况下,渲染内容用res.render(),将会根据views中的模板文件进行渲染.如果不想使用views文件夹,想自己设置文件夹名字,那么app.set("views","aaaa"); 如果想写一个快速测试页,当然可以使用res.send().这个函数将根据内容,自动帮我们设置了Content-Type头部和200状态码.send()只能用一次,和end一样.和end不一样在哪里?能够自动设置MIME类型. 如果想使用不同的状态码,可以: res.stat

  • Node.js实现分片上传断点续传示例详解

    目录 正文 文件的分片与合并 并发控制 使代码可复用 服务端接口实现 正文 大文件上传会消耗大量的时间,而且中途有可能上传失败.这时我们需要前端和后端配合来解决这个问题. 解决步骤: 文件分片,减少每次请求消耗的时间,如果某次请求失败可以单独上传,而不是从头开始 通知服务端合并文件分片 控制并发的请求数量,避免浏览器内存溢出 当因为网络或者其他原因导致某次的请求失败,我们重新发送请求 文件的分片与合并 在JavaScript中,FIle对象是' Blob '对象的子类,该对象包含一个重要的方法s

  • Node.js中创建和管理外部进程详解

    Node被设计用来高效的处理I/O操作,但是你应该知道,有些类型的程序并不适合这种模式.比如,如果你打算用Node处理一个CPU密集的任务,你可能会堵塞事件循环,并因此降低了程序的响应.替代办法是,把CPU密集的任务分配给一个单独的进程来处理,从而释放事件循环.Node允许你产生进程,并把这个新进程做为它父进程的子进程.在Node里,子进程可以和父进程进行双向通信,而且在某种程度上,父进程还可以监控和管理子进程. 另外一种需要使用子进程的情况是,当你想简单地执行一个外部命令,并让Node获取命令

  • 原生js中运算符及流程控制示例详解

    运算符 算数:+ 加.- 减.* 乘./ 除.% 求模 赋值:=.+=.-=.*=./=.%= 关系:>.<. >=. <=. ==. ===. !=. !== 逻辑:||或.&&与.!否 实例1.求模 window.onload = function(){ alert(0%2) //0 alert(1%2) //1 alert(2%2) //0 } 实例2.隔行变色 <body> <ol> <li>取模:就是求余数</li

  • Node.js中使用计时器定时执行函数详解

    如果你熟悉客户端JavaScript编程,你可能使用过setTimeout和setInterval函数,这两个函数允许延时一段时间再运行函数.比如下面的代码, 一旦被加载到Web页面,1秒后会在页面文档后追加"Hello there": 复制代码 代码如下: var oneSecond = 1000 * 1; // one second = 1000 x 1 ms setTimeout(function() { document.write('<p>Hello there.

  • Node.js中的HTTP请求与响应详解

    在C#.OC中也是客户端发起一个请求,服务端作出响应.我们可以把这个过程抽象理解 . 1.客户端给服务端发起请求相当于向服务端写入一个流(writable) 2.服务端读取客户端的流(readable) 3.服务端向客户端作出响应相当于向客户端写入一个流(writable) 4.客户端读取服务端的响应(readable) 整个流程分为两部分一是客户端的处理而是服务端的处理.最主要的还是客户端请求和服务端响应. 一.http.ClientRequest对象 它实现了writable流,可以使用它的

随机推荐