Asynchronous 是node.js';console.log异步?

Asynchronous 是node.js';console.log异步?,asynchronous,console,node.js,Asynchronous,Console,Node.js,node.js中的console.log/debug/warn/error是否异步?我的意思是,javascript代码的执行会在屏幕上打印出来之前停止,还是会在稍后的阶段打印出来 另外,我还想知道,如果console.log语句在节点崩溃后立即出现,它是否可能不显示任何内容。更新:从节点0.6开始这篇文章是过时的,因为stdout现在是同步的 让我们看看console.log实际上做了什么 首先,它是: 因此,它只需进行一些格式化并写入process.stdout,到目前为止没有任何异步操作

node.js中的
console.log/debug/warn/error
是否异步?我的意思是,javascript代码的执行会在屏幕上打印出来之前停止,还是会在稍后的阶段打印出来


另外,我还想知道,如果console.log语句在节点崩溃后立即出现,它是否可能不显示任何内容。

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

让我们看看console.log实际上做了什么

首先,它是:

因此,它只需进行一些格式化并写入
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的情况下,这个东西继承自套接字。因此,节点主要做的就是将数据推送到套接字上,然后由终端处理其余的数据

让我们测试一下

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);
终端需要大约1秒打印套接字内容,而节点只需要17毫秒将数据推送到终端

流案例也是如此,文件案例也得到了处理

因此,yesNode.js遵守其非阻塞承诺。

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


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

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

(下面的命令行示例演示了console.logasync和console.error是sync

基于

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

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

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

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


希望对您有所帮助。Console.log在windows中是异步的,而在linux/mac中是同步的。要使console.log在windows中同步,请在 代码可能在index.js文件中。此语句之后的任何console.log都将被解释器视为同步

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

您可以将其用于同步日志记录:

const fs = require('fs')
fs.writeSync(1, 'Sync logging\n')

更新:node.js中的stdout现在是同步的:我认为它现在已经过时了:@IvoWetzel我现在不得不对它进行否决,因为它已经过时了。我知道这已经过时了,但你在
process.stdout.write()
where
write()之后立即说“到目前为止没有异步”
根据定义是异步的……对于Windows中的节点0.10.25,情况并非如此
console.warn()
console.error()
具有与
console.log()
相同的非阻塞行为。甚至还有一个。什么是“海量数据”?它是由调用console.log的次数定义的还是由写入的总金额定义的?什么是1KB/ms、1MB/ms、1GB/ms?这些都是通过实验发现的:)@MattGLinux不仅仅是ubuntu。谢谢,请原谅我的迂腐评论,Debian是我的弱点,似乎现在开始使用Linux的每个人都认为ubuntu是Linux(除了你,我知道你不是其中之一)。祝您愉快:)
if (process.stdout._handle) process.stdout._handle.setBlocking(true);
const fs = require('fs')
fs.writeSync(1, 'Sync logging\n')