我正在将Node.JS与一个提供对数据进行迭代器式访问的库连接:
next = log.get_next()
我实际上想写下以下内容:
while (next = log.get_next()) {
console.log(next);
}
并将stdout
重定向到文件(例如node log.js > log.txt
)。这适用于小型日志,但对于大型批次,输出文件为空,我的内存使用量通过屋顶。
看起来我并不完全理解节点中的I / O,因为将字符串写入控制台的简单无限循环也表现出相同的行为。
关于如何完成这项任务的一些建议会很棒。感谢。
答案 0 :(得分:2)
WriteStream类缓冲i / o,如果你永远不会产生线程,那么排队的写操作永远不会得到服务。最好的方法是编写一个合理的数据块,然后在再次写入之前等待缓冲区清除。 WriteStream类发出一个'drain'事件,告诉你缓冲区何时被完全刷新。这是一个例子:
var os = require('os');
process.stdout.on('drain', function(){
dump();
});
function dump(){
for (var i=0; i<10000; i++)
console.log('xxxx');
console.error(os.freemem());
}
dump();
如果您的运行方式如下:
node testbuffer > output
你会看到文件定期增长,内存达到稳定状态。
答案 1 :(得分:0)
您正在接口的库应该接受回调。 Node.js设计为非阻塞。我想也许console.log
在发送输出之前可能会继续将控制权返回给循环(和log.get_next()
)。
如果重写模块以使get_next支持回调,改进的代码可能是这样的:
var log_next = function() {
console.log(next);
log.get_next(log_next);
};
log.get_next(log_next);
(有一些库和模式可以使这段代码更漂亮。)
如果代码只是同步并且必须保持原样,那么使用0或其他小数字调用setTimeout可以防止它阻塞整个过程。
var log_next = function() {
console.log(log.get_next());
setTimeout(log_next, 0);
};
log_next();