详解Node Stream

前言

以前基于流处理构建工具gulp介绍,如今对stream模块进行简要分析,以便更好的使用构建工具,以及进行插件开发。javascript

Stream

Stream模块有四个类,Readable, Writable, Duplex, TransformTransform能够看作自成体系的子类。从使用角度来讲,模块定义的类都为基类,是不具有直接使用条件的,须要程序实现相关接口方可以使用。java

Stream.Readable

此类须要实现_read接口,用通俗的话来说,可读流至关于发货仓库,仓库中的货物储备交由_read处理,具体发货模块内部自行处理。可读流对象有flowing modenon-flowing mode两种模式,前者自动处理发货,后者须要手动控制发货。git

javascript// inherit stream.Readable
function Love() {
  stream.Readable.call(this);
  this._max = 5;
  this._index = 0;
}
util.inherits(Love, stream.Readable);

Love.prototype._read = function() {
  var i = this._index++;
  if (i > this._max) {
    this.push('beautiful');
    this.push(null);
  }
  else {
    var str = '' + i;
    var buf = new Buffer(str, 'utf8');
    this.push(buf);
  }
};

在初始化时,会自动调用_read方法,利用ctx.push方法写入内容到内部存储buffer(进货)。代码很简单,传输的内容为0-5,以及单词beautiful。如今仓库中已经有货物,而后处理发货流程。github

flowing mode下,监听data事件便可,non-flowing mode下,使用readable.read方法获取内容,两种方式实际效果等同。此处readable事件触发比较不解,暂时没法深刻。gulp

javascript// flowing mode
title.on('data', function(data) {
  writer.write(data);
});
// non-flowing mode
title.on('readable', function() {
  var chunk;
  while (null !== (chunk = title.read())) {
    writer.write(chunk);
  }
});

至此,能够简单理解可读流就是进货出货的方式,定义接口实现进货,数据读取实现出货。工具

stream.Writable

此类须要实现_write接口,用通俗的话来说,可写流就是快递签收的过程。卖家不断发货,买家不断收货,签收的流程就是由_write接口定义。this

javascript// inherit stream.Writable
function Story() {
  stream.Writable.call(this);
  this._storage = new Buffer('');
}
util.inherits(Story, stream.Writable);

Story.prototype._write = function(chunk, encoding, callback) {
  this._storage = Buffer.concat([this._storage, chunk]);
  callback();
};

此处定义方式很简单,收到数据后,将数据保存在this._storage私有变量中,这样就定义好可写流。下面来看如何综合使用两个类。prototype

javascriptvar reader = new Love();
var writer = new Story();

reader.on('readable', function() {
  var chunk;
  while (null !== (chunk = title.read())) {
    writer.write(chunk);
  }
});

reader.on('end', function() {
  writer.end();
});

writer.on('finish', function() {
  fs.writeFileSync('./output.txt', this._storage);
});

此处使用,将可读流传下来的数据所有写入output.txt文件之中,很是简单的示例。插件

stream.Duplex

可读可写流,兼而有之二者特性,不清楚是否能够同时兼任二者,本人暂时未找处处理方案。code

stream.Transform

可以同时兼任可读流与可写流,gulp插件总结来讲,就是自定义的stream.Transform流。须要实现接口_transform_flush,二者均可以_read的特色,能够向后传递数据。

javascriptfunction Knight() {
  stream.Transform.call(this);
}
util.inherits(Knight, stream.Transform);

Knight.prototype._transform = function(chunk, encoding, callback) {
  this.push(chunk);
  callback();
};

Knight.prototype._flush = function(callback) {
  this.push('dark knight');
  callback();
};

示例很是简单,在内容后面再加上dark knight字符串,再也不赘述。

总结

对全部流来讲,一般使用pipe方法更为简便直接,因此应避免使用其余方式。完整代码地址:http://snowykiss.qiniudn.com/stream.js

联系方式

QQ: 491229492
https://github.com/bornkiller

相关文章
相关标签/搜索