我有一个 EventEmitter
对象,我设置它来监听事件。当事件发出时,我想将信息写入文件。我有一个打开的 FileStream
通过 fs.createWriteStream(path, { flags: 'a'});
目前,我的问题是如果我超快且经常发出事件,我开始“备份”。 IE .write
返回 false
要求我暂时停止写作。由于我在事件处理程序中进行写入,因此附近没有回调函数可用于指示写入过程的结束。我可以从处理端或发射端做些什么来防止备份?
最终,这似乎并不重要;所有数据都会写入文件。但我想尽我所能遵守“规则”。
我知道我可以监听 drain
事件并在之后再次开始写入,但是如何防止其他事件进入处理程序?我注意到,如果我在每次发出之前延迟 50 毫秒,备份似乎不会发生,但这看起来有点像 hack。另外,如果您的 HDD 速度较慢怎么办?
下面是我的情况的一个例子:
var ee = new EventEmitter();
var stream = fs.createWriteStream('./file/log.txt', { flags:'a'} );
ee.on('report', function (i) {
stream.write('new file data ' + i + ' --- ' + Date.now + '\n');
});
for (var i = 0; i < 10000; ++i) {
ee.emit('report', i)
}
这不是确切的代码,但这是它的要点。完整的代码发生在从正在运行的 HTTP 服务器发送响应时,但是如果我排队 1000 个请求,例如通过 for 循环,我就会遇到上述情况。
最佳答案
实际上,我最终找到了一个使用读写流来解决这个问题的更简单的解决方案。有关示例,请参见下面的代码
var stream = require('stream');
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var ee = new EventEmitter();
var writeStream = fs.createWriteStream('./file/log.txt', { flags: 'a', end: false } );
var readStream = new stream.Readable();
// This needs to be here for compatibility reasons, but is intentionally a no-op
readStream._read = function() {};
ee.on('report', function (i) {
readStream.push(i.toString());
});
readStream.pipe(writeStream);
for (var i = 0; i < 10000; ++i) {
ee.emit('report', i);
}
这将允许 Node 管道和流系统与操作系统协调处理背压。这是 IMO 解决此问题的首选方法。
关于javascript - 从事件处理程序写入 WriteStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26187181/