node.js的console.log异步?

node.js中的console.log/debug/warn/error是异步的吗? 我的意思是javascript代码执行停止,直到东西打印在屏幕上或将在稍后阶段打印?

此外,我有兴趣知道如果它后面的语句崩溃节点,console.log是否可能不显示任何内容。

dhruvbird asked 2019-09-09T14:59:29Z
4个解决方案
96 votes

更新:从Node 0.6开始,这篇文章已经过时,因为stdout现在是同步的。

好吧,让我们看看process.stdout究竟是做什么的。

首先,它是控制台模块的一部分:

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

所以它只是做了一些格式化并写入process.stdout,到目前为止没有任何异步。

process.stdout是一个在启动时定义的getter,它被懒惰地初始化,我添加了一些注释来解释一些事情:

.... 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,我们最终会在这里继承,这件事继承自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毫秒就可以将数据推送到终端。

流案例也是如此,文件大小写也是异步处理的。

所以是的Node.js坚持其非阻塞承诺。

Ivo Wetzel answered 2019-09-09T15:01:01Z
26 votes

console.warn()和console.error()是阻塞的。 在底层系统调用成功之前,它们不会返回。

是的,程序可以在刷新写入stdout的所有内容之前退出。 process.exit()将立即终止节点,即使仍有队列写入stdout。 您应该使用console.warn来避免此行为。

Matt Ranney answered 2019-09-09T15:01:35Z
11 votes

我的结论,在阅读Node.js 10. * docs(附后)。 是你可以使用console.log进行日志记录,console.log是同步的并且在低级别c中实现。虽然console.log是同步的,但只有在您没有记录大量数据时才会导致性能问题。

(下面的命令行示例演示,console.log async和console.error是同步的)

基于Node.js Doc's

当目标是终端或文件时,控制台功能是同步的(以避免在过早退出的情况下丢失消息)并且当它是管道时是异步的(以避免长时间阻塞)。

也就是说,在以下示例中,当stderr阻塞时,stdout是非阻塞的:

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

在日常使用中,除非您>记录大量数据,否则不应该担心阻塞/非阻塞二分法。

希望能帮助到你

doron aviguy answered 2019-09-09T15:02:54Z
3 votes

Console.log在Windows中是异步的,而在linux / mac中是同步的。 要使windows中的console.log同步,请在您的开头写下这一行代码可能在index.js文件中。 此语句之后的任何console.log都将被解释器视为同步。

if (process.stdout._handle) process.stdout._handle.setBlocking(true);
Ali Azlan answered 2019-09-09T15:03:20Z
translate from https://stackoverflow.com:/questions/5127532/is-node-js-console-log-asynchronous