我想在使用NodeJS的服务器群集中通过SSH抓取数据。
远程脚本输出JSON,然后将其解析并拆分为object stream。
我现在的问题是我使用的面向回调的库(SSH2,MySQL)导致回调模式,我觉得很难与Readable API规范相匹配。当要推送的数据落后于一堆回调时,如何实现_read(size)
?
我目前的实施利用了Streams
也是EventEmitters
的事实。我在构建Stream实例时开始填充数据。完成所有回调后,我会发出一个事件。然后,我听取自定义事件,然后才开始将数据向下推送到管道链中。
// Calling code
var stream = new CrawlerStream(argsForTheStream);
stream.on('queue_completed', function() {
stream
.pipe(logger)
.pipe(dbWriter)
.on('end', function() {
// Close db connection etc...
});
});

CrawlerStream
的模拟将是
// Mock of the Readable stream implementation
function CrawlerStream(args) {
// boilerplate
// array holding the data to push
this.data = [];
// semi-colon separated string of commands
var cmdQueue = getCommandQueue();
var self = this;
db.query(sql, function(err, sitesToCrawl, fields) {
var servers = groupSitesByServer(sitesToCrawl);
for (var s in servers) {
sshConnect(getRemoteServer(s), function(err, conn) {
sshExec({
ssh: conn,
cmd: cmdQueue
}, function(err, stdout, stderr) {
// Stdout is parsed as JSON
// Finally I can populate self.data!
// Check if all servers are done
// If I'm the last callback to execute
self.data.push(null);
self.emit('queue_completed');
})
});
}
});
}
util.inherits(CrawlerStream, Readable);
CrawlerStream.prototype._read = function(size) {
while (this.data.length) {
this.push(this.data.shift());
}
}

我不确定这是否是实现此目的的惯用方法,并希望得到您的建议。
请注意,在我的回答中,我希望保留使用回调(没有承诺)的香草NodeJS风格,并且我仍然坚持使用ES5。
谢谢你的时间!