node.js中Util模塊作用教程示例詳解
從類型判斷說起
在 JavaScript 中,進(jìn)行變量的類型校驗(yàn)是一個(gè)非常令人頭疼的事,如果只是簡單的使用?typeof
?會(huì)到各種各樣的問題。
舉幾個(gè)簡單的:
console.log(typeof null) // 'object' console.log(typeof new Array) // 'object' console.log(typeof new String) // 'object'
后來,大家發(fā)現(xiàn)可以使用?Object.prototype.toString()
?方法來進(jìn)行變量類型的判斷。
const getTypeString = obj => Object.prototype.toString.call(obj) getTypeString(null) // '[object Null]' getTypeString('string') //'[object String]' getTypeString(new String) //'[object String]'
對(duì)?toString()
?方法進(jìn)行代理,可以得到一個(gè)類型字符串,我們就可以在這個(gè)字符串上面搞事情。
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 中,內(nèi)部其實(shí)是有一組用來判斷變量類型的 api 的。而且功能異常豐富,除了基礎(chǔ)類型的判斷,還支持判斷 Promise 對(duì)象、Date 對(duì)象、各種ArrayBuffer。
const types = require('util/types') types.isDate(new Date) // true types.isPromise(new Promise(() => {})) // true types.isArrayBuffer(new ArrayBuffer(16)) // true
嚴(yán)格相等
在 JavaScript 中,對(duì)象、數(shù)組等變量在判斷相等的過程中,如果用?===
?通常只會(huì)判斷這兩個(gè)變量是否指向同一內(nèi)存地址。如果想判斷對(duì)象的鍵對(duì)應(yīng)的所有值是否相等,需要對(duì)兩個(gè)對(duì)象進(jìn)行遍歷。在?util
?中,也提供了一個(gè)方法可以用來判斷兩個(gè)對(duì)象是否嚴(yán)格相等: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
該方法同樣可以用來判斷數(shù)組,是否嚴(yán)格相等:
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
?風(fēng)格的,也就是所有的異步函數(shù)都會(huì)接受一個(gè)回調(diào)函數(shù),該回調(diào)的一個(gè)參數(shù)為 error 對(duì)象,如果正常返回 error 對(duì)象為?null
,后面的參數(shù)為成功響應(yīng)的結(jié)果。
// 下面是一個(gè)讀取文件的示例 const fs = require('fs') fs.readFile('nginx.log', (error, data) => { if (error) { // 讀取文件失敗 console.error(error) return } // 讀取文件成功,打印結(jié)果 console.log(data) })
在 Node 8 發(fā)布的時(shí)候,新增了一個(gè)?promisify
?接口,用于將?Error First
?風(fēng)格的 API 轉(zhuǎn)為 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 的方式太過繁瑣,每個(gè) API 都需要單獨(dú)的包裝一層?promisify
?方法。在 Node 10 發(fā)布的時(shí)候,原生模塊都新增了一個(gè)?.promises
?屬性,該屬性下的所有 API 都 Promise 風(fēng)格的。
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
?風(fēng)格的 API 轉(zhuǎn)為 Promise API,util
?中還提供?callbackify
?方法,用于將?async
?函數(shù)轉(zhuǎn)換為?Error First
?風(fēng)格的函數(shù)。
下面通過?callbackify
?將 promise 化的?fs
?還原為?Error First
?風(fēng)格的函數(shù)。
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) })
調(diào)試與輸出
如果有開發(fā)過 Node 服務(wù),應(yīng)該都用過?debug
?模塊,通過該模塊可以在控制臺(tái)看到更加明晰的調(diào)試信息。
const debug = require('debug') const log = debug('app') const user = { name: 'shenfq' } log('當(dāng)前用戶: %o', user)
其實(shí),通過?util.debug
?也能實(shí)現(xiàn)類似的效果:
const debug = require('debug') const log = debug('app') const user = { name: 'shenfq' } log('當(dāng)前用戶: %o', user)
只是在啟動(dòng)時(shí),需要將?DEBUG
?環(huán)境變量替換為?NODE_DEBUG
。
如果你有認(rèn)真看上面的代碼,應(yīng)該會(huì)發(fā)現(xiàn),在?log('當(dāng)前用戶: %o', user)
?方法前面的字符串中,有一個(gè)?%o
?占位符,表示這個(gè)地方將會(huì)填充一個(gè)對(duì)象(object)。這與 C 語言或 python 中的,printf
?類似。同樣,在?util
?模塊中,直接提供了格式化的方法:util.format
。
const { format } = require('util') console.log( format('當(dāng)前用戶: %o', { name: 'shenfq', age: 25 }) )
除了?%o
?占位符,不同的數(shù)據(jù)類型應(yīng)使用不同的占位符。
占位符 | 類型 |
---|---|
%s | 字符串 |
%d | 數(shù)字(包括整數(shù)和浮點(diǎn)數(shù)) |
%i | 整數(shù) |
%f | 浮點(diǎn)數(shù) |
%j | JSON |
%o | Object |
JavaScript 中的對(duì)象是一個(gè)很復(fù)雜的東西,除了直接使用?util.format
?外加?%o
?占位符的方式格式化對(duì)象,util
?中還提供了一個(gè)叫做?inspect
?方法來進(jìn)行對(duì)象格式化。
const { inspect } = require('util') const user = { age: 25, name: 'shenfq', work: { name: 'coding', seniority: 5 } } console.log(inspect(user))
這么看?inspect
?好像什么都沒做,但是?inspect
?方法還有第二個(gè)參數(shù),用來進(jìn)行格式化時(shí)的一些個(gè)性化配置。
depth: number
:控制顯示層級(jí);
sorted: boolean|Function
: 是否按照key的編碼值進(jìn)行排序;
compact: boolean
:是否進(jìn)行單行顯示;
當(dāng)然上面只是一部分配置,更詳細(xì)的配置可查閱 node 文檔,下面我們寫幾個(gè)案例:
所有的屬性都換行顯示:
inspect(user, { compact: false })
只格式化對(duì)象第一層的值:
inspect(user, { depth: 0, compact: false })
按照key值的編碼倒序輸出:
inspect(user, { compact: false, sorted: (a, b) => a < b ? 1 : -1 })
以上就是node.js中Util模塊教程示例詳解的詳細(xì)內(nèi)容,更多關(guān)于node.js中Util模塊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Nodejs實(shí)現(xiàn)短信驗(yàn)證碼功能
使用Nodejs的開發(fā)者愈來越多,基于Nodejs的后臺(tái)開發(fā)也多了起來,像短信驗(yàn)證碼、短信群發(fā)、國際短信這些需求,完全可以采用第三方接口來實(shí)現(xiàn),云片就提供了這樣的接口2017-02-02node.js+express留言板功能實(shí)現(xiàn)示例
本文介紹基于nodejs+express+art-template的留言板功能。包含列表界面、添加界面和發(fā)送留言功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09node.js 使用ejs模板引擎時(shí)后綴換成.html
本文給大家分享一個(gè)nodejs的小技巧,將ejs模板引擎的模板后綴改成.html的使用方法,非常的簡單實(shí)用,這里推薦給大家。2015-04-04手把手教你更優(yōu)雅的修改node_modules里的代碼
這篇文章主要給大家介紹了關(guān)于如何更優(yōu)雅的修改node_modules里的代碼的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-02-02