node.js 的 console.log 是异步的吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5127532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:53:33  来源:igfitidea点击:

is node.js' console.log asynchronous?

asynchronousconsolenode.js

提问by dhruvbird

Are console.log/debug/warn/errorin node.js asynchrounous? I mean will javascript code execution halt till the stuff is printed on screen or will it print at a later stage?

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

Also, I am interested in knowing if it is possible for a console.log to NOT display anything if the statement immediately after it crashes node.

另外,我有兴趣知道如果该语句在节点崩溃后立即显示,console.log 是否有可能不显示任何内容。

回答by Ivo Wetzel

Update:Starting with Node 0.6 this post is obsolete, since stdout is synchronousnow.

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

Well let's see what console.logactually does.

好吧,让我们看看console.log实际做了什么。

First of all it's part of the console module:

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

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

So it simply does some formatting and writes to process.stdout, nothing asynchronous so far.

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

process.stdoutis a getter defined on startupwhich is lazily initialized, I've added some comments to explain things:

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;
});

In case of a TTY and UNIX we end up here, this thing inherits from socket. So all that node bascially does is to push the data on to the socket, then the terminal takes care of the rest.

在 TTY 和 UNIX 的情况下,我们在这里结束,这个东西继承自 socket。因此,该节点基本上所做的就是将数据推送到套接字,然后终端负责其余的工作。

Let's test it!

让我们来测试一下!

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);

Result

结果

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

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

The terminal needs around 1 seconds to print out the sockets content, but node only needs 17 milliseconds to push the data to the terminal.

终端需要大约 1 秒的时间打印出套接字内容,而节点只需要 17 毫秒将数据推送到终端。

The same goes for the stream case, and also the file case gets handle asynchronous.

流案例也是如此,文件案例也得到了句柄asynchronous

So yesNode.js holds true to its non-blocking promises.

所以是的,Node.js 兑现了它的非阻塞承诺。

回答by Matt Ranney

console.warn() and console.error() are blocking. They do not return until the underlying system calls have succeeded.

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

Yes, it is possible for a program to exit before everything written to stdout has been flushed. process.exit() will terminate node immediately, even if there are still queued writes to stdout. You should use console.warn to avoid this behavior.

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

回答by doron aviguy

My Conclusion , after reading Node.js 10.* docs (Attached below). is that you can use console.log for logging , console.logis synchronous and implemented in low level c . Although console.log is synchronic, it wont cause a performance issue only if you are not logging huge amount of data.

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

(The command line example below demonstrate, console.log asyncand console.error is sync)

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

Based on Node.js Doc's

基于Node.js 文档

The console functions are synchronous when the destination is a terminal or a file (to avoid lost messages in case of premature exit) and asynchronous when it's a pipe (to avoid blocking for long periods of time).

That is, in the following example, stdout is non-blocking while stderr is blocking:

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

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

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

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

In daily use, the blocking/non-blocking dichotomy is not something you should worry about unless you > log huge amounts of data.

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

Hope it helps

希望能帮助到你

回答by Ali Azlan

Console.log is asynchronous in windows while it is synchronous in linux/mac. To make console.log synchronous in windows write this line at the start of your code probably in index.js file. Any console.log after this statement will be considered as synchronous by interpreter.

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

if (process.stdout._handle) process.stdout._handle.setBlocking(true);