Node.js 環境下的 console.log 是同步執行的

參考這個官網

通常,從您的應用程序進行日誌記錄有兩個原因:用於調試和記錄應用程序活動(本質上是其他所有內容)。使用 console.log() 或 console.error() 將日誌消息打印到終端是開發中的常見做法。 但是當目標是終端或文件時,這些函數是同步的,因此它們不適合生產,除非您將輸出通過管道傳輸到另一個程序。

https://nodejs.org/api/console.html#console_console_1

控制檯模塊提供了一個簡單的調試控制檯,類似於 Web 瀏覽器提供的 JavaScript 控制檯機制。

該模塊導出兩個特定組件:

一個 Console 類,帶有可用於寫入任何 Node.js 流的 console.log()、console.error() 和 console.warn() 等方法。
配置爲寫入 process.stdout 和 process.stderr 的全局控制檯實例。無需調用 require('console') 即可使用全局控制檯。
警告:全局控制檯對象的方法既不像它們相似的瀏覽器 API 那樣始終同步,也不像所有其他 Node.js 流那樣始終異步。有關更多信息,請參閱有關進程 I/O 的說明。

使用全局控制檯的示例:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

使用 Console class 的例子:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

process.stdout 和 process.stderr 在下列方面與其他 Node.js 流不同:

  • 它們分別由 console.log() 和 console.error() 在內部使用。
  • 寫入可能是同步的,具體取決於流所連接的內容以及系統是 Windows 還是 POSIX:
  • 文件:在 Windows 和 POSIX 上同步
  • TTY(終端):在 Windows 上異步,在 POSIX 上同步
  • 管道(和套接字):在 Windows 上同步,在 POSIX 上異步

這些行爲部分是出於歷史原因,因爲更改它們會導致向後不兼容,但某些用戶也期望它們。

同步寫入避免了諸如使用 console.log() 或 console.error() 寫入的輸出意外交錯的問題,或者如果在異步寫入完成之前調用 process.exit() 則根本不寫入。有關更多信息,請參閱 process.exit()。

警告:同步寫入會阻塞事件循環,直到寫入完成。在輸出到文件的情況下,這幾乎是瞬時的,但在高系統負載下,接收端沒有讀取管道,或者終端或文件系統緩慢,事件循環可能經常被阻塞並且時間長到足以對性能產生嚴重的負面影響。這在寫入交互式終端會話時可能不是問題,但在對流程輸出流進行生產日誌記錄時要特別小心。

要檢查流是否連接到 TTY 上下文,請檢查 isTTY 屬性。

例如:

$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false
$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false

https://nodejs.org/api/process.html#processstdout

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章