2011-02-26 118 views
75

console.log/debug/warn/error in node.js asynchrounous?我的意思是將JavaScript代碼執行停止,直到東西被打印在屏幕上或將在稍後階段打印?是node.js的console.log異步?

另外,我有興趣知道console.log是否可能不顯示任何東西,如果緊跟在它後面的語句崩潰了節點。

回答

89

更新:與節點0.6這篇文章開始已經過時了,因爲stdout是現在同步

那我們來看看console.log實際上做了什麼。所有的

首先它是console module的一部分:

exports.log = function() { 
    process.stdout.write(format.apply(this, arguments) + '\n'); 
}; 

所以它只是做一些格式化並寫入process.stdout,沒什麼異步至今。

process.stdout是一個getter defined on startup這是延遲初始化的,我加入了一些註釋來解釋的東西:

.... code here... 
process.__defineGetter__('stdout', function() { 
    if (stdout) return stdout;       // only initialize it once 

    /// many requires here ... 

    if (binding.isatty(fd)) {        // a terminal? great! 
    stdout = new tty.WriteStream(fd); 
    } else if (binding.isStdoutBlocking()) {    // a file? 
    stdout = new fs.WriteStream(null, {fd: fd}); 
    } else { 
    stdout = new net.Stream(fd);      // a stream? 
                 // For example: node foo.js > out.txt 
    stdout.readable = false; 
    } 

    return stdout; 
}); 

在TTY和UNIX我們最終here的情況下,這件事情從插座繼承。因此,該節點基本上所做的就是將數據推送到套接字上,然後終端負責其餘部分。

讓我們測試一下!

var data = '111111111111111111111111111111111111111111111111111'; 
for(var i = 0, l = 12; i < l; i++) { 
    data += data; // warning! gets very large, very quick 
} 

var start = Date.now(); 
console.log(data); 
console.log('wrote %d bytes in %dms', data.length, Date.now() - start); 

結果

....a lot of ones....1111111111111111 
wrote 208896 bytes in 17ms 

real 0m0.969s 
user 0m0.068s 
sys 0m0.012s 

終端需要大約1秒至打印出插座的內容,但節點只需要17毫秒的數據推送到該終端。

對於流案例也是一樣,並且文件案例也得到處理asynchronous

所以 Node.js適用於其非阻塞的承諾。

+2

更新:在node.js的stdout是現在同步:http://groups.google.com/group/nodejs/browse_thread/thread/8c85c2dae1a1f585 – dhruvbird 2012-03-22 03:46:48

+1

我覺得現在這已經過時了: https://github.com/nodejs/node/issues/3524#issuecomment-151097761 – tforgione 2016-07-21 08:32:53

+0

@IvoWetzel我現在不得不現在放棄它,因爲它已經過時了。 – 2017-07-12 21:33:23

23

console.warn()和console.error()被阻塞。直到底層系統調用成功爲止,它們纔會返回。

是的,在寫入標準輸出的所有內容都被刷新之前,程序可能會退出。 process.exit()會立即終止節點,即使仍然有對stdout的排隊寫入。你應該使用console.warn來避免這種行爲。

+1

對於節點0.10.25這不是真的在Windows中。 'console.warn()'和'console.error()'具有與'console.log()'相同的非阻塞行爲。甚至有一個[用於解決Windows中問題的軟件包](https://www.npmjs.org/package/exit)。 – 2014-02-14 03:17:18

9

我的結論是,在閱讀Node.js之後10. * docs(附在下面)。是您可以使用console.log進行日誌記錄,console.log是同步的,並在低級別中實現c。 儘管console.log是同步的,但只有在不記錄大量數據的情況下才會導致性能問題。

(以下命令行示例演示,console.log async和控制檯。誤差爲同步

基於Node.js Doc's

控制檯功能是同步的,當目的地是終端或文件(以避免過早退出的情況下,丟失的消息)和異步當它是一個管(以避免長時間阻塞)。

也就是說,在下面的例子中,stdout是非阻塞的,而標準錯誤阻止:

$ node script.js 2> error.log | tee info.log

在日常使用中,阻塞/非阻塞二分法是不是你應該擔心,除非你>記錄海量數據。

希望它可以幫助