node.js中的console.log/debug/warn/error
是否异步?我的意思是javascript代码执行停止,直到东西打印在屏幕上或将在稍后阶段打印?
此外,我有兴趣知道如果紧跟在节点之后的语句崩溃节点,console.log是否可能不显示任何内容。
答案 0 :(得分:96)
更新:从Node 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,这件事继承自socket。因此,所有节点基本上都是将数据推送到套接字,然后终端负责其余部分。
让我们测试一下吧!
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坚持其非阻塞承诺。
答案 1 :(得分:26)
console.warn()和console.error()正在阻止。在基础系统调用成功之前,它们不会返回。
是的,程序可以在刷新写入stdout的所有内容之前退出。 process.exit()将立即终止节点,即使仍有队列写入stdout。您应该使用console.warn来避免此行为。
答案 2 :(得分:11)
我的结论,在阅读Node.js 10. * docs之后(附于下文)。是你可以使用console.log进行日志记录, console.log 是同步的,并在低级别c中实现。 尽管console.log是同步的,但只有在您没有记录大量数据时才会导致性能问题。
(以下命令行示例演示,console.log async 和console.error 同步)
当目标是终端或文件时,控制台功能是同步的(以避免在过早退出时丢失消息),并且当它是管道时异步(以避免长时间阻塞)。
也就是说,在以下示例中,当stderr阻塞时,stdout是非阻塞的:
$ node script.js 2> error.log | tee info.log
在日常使用中,阻止/非阻塞二分法不是你应该担心的事情,除非你&gt;记录大量数据。
希望有所帮助
答案 3 :(得分:3)
Console.log在Windows中是异步的,而在linux / mac中是同步的。要使windows中的console.log同步,请在您的开头写下这一行 代码可能在index.js文件中。此语句之后的任何console.log都将被解释器视为同步。
if (process.stdout._handle) process.stdout._handle.setBlocking(true);
答案 4 :(得分:0)
您可以将其用于同步日志记录:
const fs = require('fs')
fs.writeSync(1, 'Sync logging\n')