您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何理解node.js中Util模塊作用,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
在 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
早期的 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模塊作用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。