dhr*_*ird 90 console asynchronous node.js
是console.log/debug/warn/error在node.js中-异步?我的意思是javascript代码执行停止,直到东西打印在屏幕上或将在稍后阶段打印?
此外,我有兴趣知道如果它后面的语句崩溃节点,console.log是否可能不显示任何内容.
Ivo*_*zel 98
更新:从Node 0.6开始,这篇文章已经过时,因为stdout 现在是同步的.
好吧,让我们看看究竟console.log做了什么.
首先,它是控制台模块的一部分:
exports.log = function() {
process.stdout.write(format.apply(this, arguments) + '\n');
};
Run Code Online (Sandbox Code Playgroud)
所以它只是做了一些格式化和写入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;
});
Run Code Online (Sandbox Code Playgroud)
如果是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);
Run Code Online (Sandbox Code Playgroud)
结果
....a lot of ones....1111111111111111
wrote 208896 bytes in 17ms
real 0m0.969s
user 0m0.068s
sys 0m0.012s
Run Code Online (Sandbox Code Playgroud)
终端需要大约1秒钟来打印出套接字内容,但是节点只需要17毫秒就可以将数据推送到终端.
流案例也是如此,文件大小写也是异步处理的.
所以是的 Node.js坚持其非阻塞承诺.
Mat*_*ney 26
console.warn()和console.error()是阻塞的.在底层系统调用成功之前,它们不会返回.
是的,程序可以在刷新写入stdout的所有内容之前退出.process.exit()将立即终止节点,即使仍有队列写入stdout.您应该使用console.warn来避免此行为.
dor*_*guy 12
我的结论,在阅读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
在日常使用中,除非您>记录大量数据,否则不应该担心阻塞/非阻塞二分法.
希望能帮助到你