NodeJS:可读对象流,用于异步生成数据的模式

时间:2016-07-26 18:49:34

标签: javascript node.js ssh web-scraping readable

我想在使用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。

谢谢你的时间!

0 个答案:

没有答案