javascript - 从事件处理程序写入 WriteStream

标签 javascript node.js event-handling

我有一个 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/

相关文章:

javascript - 如何将 JSON 对象/模型添加到 Whitestorm.js 世界/场景中?

node.js - 使用正则表达式捕获utf-8格式的日期

javascript - 为什么 event.ctrlKey 返回 undef?

android - 只有 recyclerview 单元格中的图标是可点击的

javascript - 有没有办法让 vue 组件准备好(初始化)

javascript - 使用多维数组进行字符串化给出空结果

javascript - Node.js mysql 查询行

javascript - '类型错误 : Object is not a function' when using tunnel-ssh

C++ Win32 键盘事件

javascript - 根据父位置滚动 div