继承关系
classDiagram
EventEmitter <|-- Stream
Stream <|-- Readable
Stream <|-- Writable
Readable <|-- Duplex
Writable <|-- Duplex
Duplex <|-- Transform
Transform <|-- PassThrough
流都是可以被继承的
-
继承Readable 复写_read 只要有on data监听,流还有数据,就不断自调用(不断读,内部记录了每次读的大小,当前应读哪个位置到哪个位置)-------经常可读流会被调一个this.push意思就是往可读流的缓冲区放数据
-
继承Writable 复写_write, 外部调用写数据会传个回调。内部不断往缓冲区放,每次放都检查缓冲区是否满了,满了就真实的写(利用回调做连锁写入),内部也是维护了上次写到哪儿了。本次写多少进去。
-
读写都是往缓冲区,释放数据Readable是on或者pipe(其实就是on),Writable就是flush之类的,具体参考文档
-
继承duplex自然是复写_read & 复写_write
-
Transform复写多了一个_transform, 在别人调_write会调_transform,自动把传入next的数据放入自己的可读流里,也就是this.push
function Transform(options) {
Duplex.call(this, options);
if (options.transform) this._transform = options.transform;
}
Transform.prototype._write = function (chunk, encoding, next) {
this._transform(chunk, encoding, (err, data) => {
if (data) {
this.push(data);
}
next(err);
});
}
- through就是Transform,没啥区别
流都有对象模式,objectMode: true,读出来的write进去的,就都是每次写入、读出的对象
- 常见用法
- read.pipe(write).write
- read.pipe(transform).write
source: pipe(param): read.on('data', () => {
param._write()
})
glob
- glob能match出跟这类形式字符串匹配的所有的文件
"src/**/*.xxx"
, glob-parent to-absolute-glob可以获取基于"src/**/*.xxx"
的绝对路径,父目录。 - 这里有个稀奇的点如果一个数据源数据量庞大,需要切分不断传给某个类对象,就可以让那个类继承可读流,然后收到数据不断this.push, 那么它的对象就可以通过on data不断拿数据。
vinyl
- 虚拟文件对象,就是一个JS对象,用来描述一个文件的
- 对象里的content要么是buffer,要么是stream