2011-02-26 113 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

在日常使用中,阻塞/非阻塞二分法是不是你应该担心,除非你>记录海量数据。

希望它可以帮助