Node.js Console

Console

穩定性:2-Stable

0x01 你真的了解Node.js的console嗎

Console模塊與瀏覽器端JavaScript的console的機制是相似的。說起console,大家的腦海里第一時間想到的可能就是console.log(),沒錯,它是JavaScript常用的調試方法;其實除了console.log(),Node.js的Console還給開發者提供了其他的調試方法,靈活地使用他們,將更好地幫助我們調試程序。
Console分為兩部分:

  • Console類,其方法可以把輸出的內容寫入到任意的Node.js流,例如console.log(),console.error()console.warn()等方法
  • 全局對象console,可以把輸出的內容寫入process.stdoutprocess.stderr。因為是全局對象,可以直接使用,不需要調用require('console')

警告:全局對象console的方法既不是同步的,例如瀏覽器端的console APIs;也不是異步的,例如Node.js的流;具體請參考 Note on process I/O 。本文有一些內容涉及到 Node.js 的 Util 模塊,如有疑問請參考作者的文章 Node.js Utilities

0x02 Class:Console

Class:Console可以通過配置輸出流來創建一個簡單的日志功能,可以通過下面兩種方式調用

const Console = require('console').Console;
const Console = console.Console;
new Console(stdout[, stderr])

創建一個Console實例,其參數是一個或連個可寫流

  • stdout 是一個可寫流,把log或info的輸出寫入到這個流
  • stderr 是一個可寫流,把warn或error的輸出寫入到這個流,如果不傳這個參數,warn和error的輸出將寫入到stdout

利用這個構造函數我們可以做一個簡單的logger系統

const fs = require('fs')
const Console = console.Console

const output = fs.createWriteStream('./stdout.log')//Node.js可寫的文件流
const errorOutput = fs.createWriteStream('./stderr.log')//Node.js可寫的文件流
const logger = new Console(output, errorOutput)//構造Console實例

// 寫入output,也就是stdout.log
logger.log('log')
logger.info('info')
// 寫入errorOutput,也就是文件stderr.log
logger.error('error')
logger.warn('warn')

全局變量console其實是一個特殊的Console實例,它把輸出寫入到process.stdoutprocess.stderr,等價于:

new Console(process.stdout, process.stderr);
console.dir(obj[, options])

這個方法等價于console.log(util.inspect(obj[, options]))

const util = require('util')
let obj = {
  obj: 'sdfsdfwer',
  number: 123,
  test:[1,2,3]
}
let opt = {colors:true}
// 下面兩行代碼是等價的,而且輸出的字符是帶顏色的,特別醒目
console.dir(obj, opt)
console.log(util.inspect(obj, opt))

console.log([data][, ...args])和console.info([data][, ...args])

console.logconsole.info是等價的,把信息輸出到stdout,可以傳多個參數,類似于linux開發的 printf方法 。這里有二個細節,第一,輸出的信息結尾都會加上換行符;第二,所有的參數都先傳給util.format()進行格式化,然后再輸出

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
console.error([data][, ...args])和console.warn([data][, ...args])

console.errorconsole.warn是等價的,把信息輸出到stderr,其他的使用方法跟console.log一樣

const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
console.time(label)和console.timeEnd(label)

這兩個方法通常一起使用來計算某些程序的運行時間。調用console.time(label)時會開啟一個計時器,計時器通過參數label進行區分,當調用console.timeEnd(label)時,相同label的計時器就會停止,同時,會計算從計時器開始到結束這期間的毫秒數,并將結果輸出到stdout,精確度是亞毫秒

console.time('100-elements');
for (let i = 0; i < 100; i++) {
  ;
}
console.timeEnd('100-elements');
// prints 100-elements: 0.060ms

注意:從Node.js v6.0.0起,調用console.timeEnd()會刪除計時器以避免其泄露。在之前的版本,計時器將會繼續,不會刪除。這可能會造成同一個label,調用多次console.timeEnd()的情況,所以這種情況之前Node.js社區的人也沒有想到,v6版本以后就不會再出現了

console.trace(message[, ...args])

首先把字符串'Trace: messsage'打印出來,然后再把代碼中當前位置的堆棧跟蹤信息通過util.format()格式化后打印到stderr。

console.trace('Show me');
// Prints: (stack trace will vary based on where trace is called)
//  Trace: Show me
//    at repl:2:9
//    at REPLServer.defaultEval (repl.js:248:27)
//    at bound (domain.js:287:14)
//    at REPLServer.runBound [as eval] (domain.js:300:12)
//    at REPLServer.<anonymous> (repl.js:412:12)
//    at emitOne (events.js:82:20)
//    at REPLServer.emit (events.js:169:7)
//    at REPLServer.Interface._onLine (readline.js:210:10)
//    at REPLServer.Interface._line (readline.js:549:8)
//    at REPLServer.Interface._ttyWrite (readline.js:826:14)
console.assert(value[, message][, ...args])

這個功能可以做一個簡單的斷言測試,如果參數valuefalse,則會拋出一個AssertionError的錯誤,錯誤信息都是通過util.format()格式化的

console.assert(true, 'does nothing');
// OK
console.assert(false, 'Whoops %s', 'didn\'t work');
// AssertionError: Whoops didn't work

注意:Node.js的console.assert()與瀏覽器端的實現是不一樣的,詳細點說,瀏覽器端的console.assert()如果斷言錯誤則會打印錯誤信息到控制臺,不會終止運行后續的代碼。但在Node.js中,會拋出AssertionError錯誤。
如果要在Node.js環境實現瀏覽器端的console.assert()功能,可以擴展Node.js的console來重寫console.assert()方法

'use strict';

// Creates a simple extension of console with a
// new impl for assert without monkey-patching.
const myConsole = Object.create(console, {
  assert: {
    value: function assert(assertion, message, ...args) {
      try {
        console.assert(assertion, message, ...args);
      } catch (err) {
        console.error(err.stack);
      }
    },
    configurable: true,
    enumerable: true,
    writable: true,
  },
});

module.exports = myConsole;

再創建一個文件引入myConsole,這時console.assert()與瀏覽器端的console.assert()是一樣的

const console = require('./myConsole');
console.assert(false, 'this message will print, but no error thrown');
console.log('this will also print');//不會拋出AssertionError,代碼會繼續執行

本文檔是根據文檔Node.js v6.10.2 Documentation進行總結的,如您在閱讀的過程中發現問題,請聯系作者,感謝您的支持!

簡書作者 小菜荔枝 轉載請聯系作者獲得授權

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Node.js 全局對象 JavaScript 中有一個特殊的對象,稱為全局對象(Global Object),它...
    FTOLsXD閱讀 410評論 0 2
  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測試 ...
    KeKeMars閱讀 6,396評論 0 6
  • Node.js是目前非常火熱的技術,但是它的誕生經歷卻很奇特。 眾所周知,在Netscape設計出JavaScri...
    w_zhuan閱讀 3,639評論 2 41
  • 個人入門學習用筆記、不過多作為參考依據。如有錯誤歡迎斧正 目錄 簡書好像不支持錨點、復制搜索(反正也是寫給我自己看...
    kirito_song閱讀 2,500評論 1 37
  • 誰也不知道另一個人的記憶所止處,這句話出自《邊城》。其實我們生活中的矛盾,苦惱多數也是不明白另一個人的記憶所止處。...
    菊子跳跳閱讀 1,373評論 0 1