Util module in node.js tutorial example detailed explanation

Util module in node.js tutorial example detailed explanation

Starting from type judgment

In JavaScript, variable type checking is a very troublesome thing. If you simply use typeof you will encounter various problems.

Here are a few simple ones:

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

Later, everyone discovered that Object.prototype.toString() method could be used to determine the type of variable.

const getTypeString = obj => Object.prototype.toString.call(obj)
 
getTypeString(null) // '[object Null]'
getTypeString('string') //'[object String]'
getTypeString(new String) //'[object String]'

By proxying toString() method, we can get a type string, and we can do something with this string.

const getTypeString = obj => {
  return Object.prototype.toString.call(obj)
}
const isType = type => {
  return obj => {
    return getTypeString(obj) === `[object ${type}]`
  }
} 
const isArray = isType('Array') // This method is generally replaced by 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, in Node.js, there is actually a set of APIs for determining variable types. And it has extremely rich functions. In addition to the judgment of basic types, it also supports the judgment of Promise objects, Date objects, and various ArrayBuffers.

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

Strict equality

In JavaScript, when judging the equality of objects, arrays and other variables, if === is used, it usually only judges whether the two variables point to the same memory address. If you want to determine whether all the values ​​corresponding to the keys of the objects are equal, you need to traverse the two objects. In util , there is also a method that can be used to determine whether two objects are strictly equal: 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

This method can also be used to determine whether arrays are strictly equal:

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

Early Node APIs were all Error First style, that is, all asynchronous functions would accept a callback function, one parameter of which was an error object. If the error object was returned normally, it would be null , and the subsequent parameters would be the result of a successful response.

// Here is an example of reading a file const fs = require('fs')
fs.readFile('nginx.log', (error, data) => {
  if (error) {
    // Failed to read the file console.error(error)
    return
  }
  // Read the file successfully, print the result console.log(data)
})

When Node 8 was released, a new promisify interface was added to convert Error First style API to the 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))

However, many people later felt that the way these native APIs support Promise is too cumbersome, and each API needs to be wrapped with a separate promisify method. When Node 10 was released, native modules added a .promises property, and all APIs under this property are Promise-style.

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

Note: After Node 14, a new way to import promises API is added, which is to import by modifying the package name.

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

In addition to converting Error First style API to the Promise API, util also provides a callbackify method for converting an async function to an Error First style function.

Next, callbackify is used to restore the promise-ified fs to an Error First style function.

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

Debugging and Output

If you have developed a Node service, you should have used the debug module, which allows you to see clearer debugging information in the console.

const debug = require('debug')
const log = debug('app')
const user = { name: 'shenfq' } 
log('Current user: %o', user)

In fact, a similar effect can be achieved through util.debug :

const debug = require('debug')
const log = debug('app')
const user = { name: 'shenfq' } 
log('Current user: %o', user)

Just replace the DEBUG environment variable with NODE_DEBUG when starting.

If you look carefully at the code above, you will find that there is a %o placeholder in the string before log('當前用戶: %o', user) method, indicating that this place will be filled with an object. This is similar to printf in C or Python. Similarly, in the util module, the formatting method is directly provided: util.format .

const { format } = require('util')
console.log(
  format('Current user: %o', {
    name: 'shenfq', age: 25
  })
)

In addition to %o placeholder, different placeholders should be used for different data types.

Placeholder type
%s String
%d Numbers (both integers and floating point numbers)
%i Integer
%f Floating point numbers
%j JSON
%o Object

Objects in JavaScript are very complex. In addition to directly using util.format with %o placeholder to format objects, util also provides a method called inspect to format objects.

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

It seems that inspect does nothing, but the inspect method has a second parameter for some personalized configuration during formatting.

depth: number : controls the display level;

sorted: boolean|Function : whether to sort by the encoded value of the key;

compact: boolean : whether to display in single line;

Of course, the above is only part of the configuration. For more detailed configuration, please refer to the node documentation. Let's write a few examples below:

All properties are displayed in line breaks:

inspect(user, {
    compact: false
})

Format only the first level value of an object:

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

Output in reverse order according to the key value encoding:

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

The above is the detailed content of the tutorial example of the Util module in node.js. For more information about the Util module in node.js, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of NodeJS modularity
  • Detailed explanation of nodejs built-in modules
  • Node.js API detailed explanation of util module usage example analysis
  • Analysis of the usage of common tool modules util based on nodejs
  • Node.js common tools util module

<<:  Sharing of two website page translation plug-ins

>>:  Example code for implementing a three-column layout with CSS, where the middle column is adaptive and changes width with text size

Recommend

Detailed discussion of memory and variable storage in JS

Table of contents Preface JS Magic Number Storing...

Implementation of CSS linear gradient concave rectangle transition effect

This article discusses the difficulties and ideas...

Linux server SSH cracking prevention method (recommended)

1. The Linux server configures /etc/hosts.deny to...

Example code for implementing the wavy water ball effect using CSS

Today I learned a new CSS special effect, the wav...

How to allow remote access to open ports in Linux

1. Modify the firewall configuration file # vi /e...

Detailed summary of mysql sql statements to create tables

mysql create table sql statement Common SQL state...

IIS7~IIS8.5 delete or modify the server protocol header Server

Requirements: Remove HTTP response headers in IIS...

Detailed explanation of the processing of the three Docker Nginx Logs

Because colleagues in the company need Nginx log ...

Detailed example of creating and deleting tables in MySQL

The table creation command requires: The name of...

Vue two fields joint verification to achieve the password modification function

Table of contents 1. Introduction 2. Solution Imp...

SpringBoot integrates Activiti7 implementation code

After the official release of Activiti7, it has f...

Example code for implementing hollowing effect with CSS

Effect principle Mainly use CSS gradient to achie...

How to backup MySQL regularly and upload it to Qiniu

In most application scenarios, we need to back up...

Teach you how to build hive3.1.2 on Tencent Cloud

Environment Preparation Before starting any opera...