如果将文件可写流传递给Node.js中的Console构造函数,是否异步写入它?

pap*_*iro 13 logging asynchronous node.js

我已经阅读了有关Console对象的文档和关于进程I/O的说明,但无法确定以下是否会导致同步或异步操作:

const out = fs.createWriteStream('./out.log')
const logger = new Console(out)

logger.log('foo')
Run Code Online (Sandbox Code Playgroud)

我很好奇它是如何起作用的,特别是在*Nix系统上.但我不希望这在Windows上采取不同的行为.我问的原因是因为我已经构建了一个利用Console对象的记录器,但我不希望在生产过程中将日志写入文件时阻塞记录器.

Kay*_*eri 5

tldr;
根据 Node 的官方文档,您在这里所做的是同步的,因为您使用的是files


根据流所连接的内容以及系统是 Windows 还是 Unix,写入可能是同步的:

  • 文件:在 Windows 和 Linux 上同步
  • TTYs(终端):在 Windows 上异步,在 Unix 上同步
  • 管道(和套接字):在 Windows 上同步,在 Unix 上异步

警告:我强烈建议不要在生产服务上使用这些同步操作,因为同步写入会阻塞事件循环,直到写入完成。在进行生产日志记录时,这可能是一个严重的缺点。

参考:Node.js 官方文档/进程 I/O 说明


小智 5

它将是异步的

Console类内部维护了一个回调_stdoutErrorHandler,在写操作完成后触发并检查错误。我们可以使用它来测试异步性。

const fs = require('fs');
const { Console } = require('console');
const str = new Array(100).fill('').map(() => 'o'.repeat(1000 * 1000)).join('');
const out = fs.createWriteStream('./o.txt');
const logger = new Console(out);
logger._stdoutErrorHandler = () => { console.log('written');};
logger.log(str);
console.log('hey');
Run Code Online (Sandbox Code Playgroud)

你会看到“嘿”在“写”之前被打印出来。

关于进程 I/O 的注意事项适用于process.stdinprocess.stdout哪些是特殊流。当它们指向文件时,如下所示:

$ node someCode.js > file.txt
Run Code Online (Sandbox Code Playgroud)

... 在 Unix 中,Unix 中的写操作将是同步的。这是在这里按行处理的。在这种情况下,process.stdout流将连接到文件而不是通常的 unix 文件描述符fd1