前几篇文章主要讲了可读流、可写流以及pipe方法,这篇文章主要介绍一下Duplex流和Transform流!

Duplex流

这个流比较简单,它主要继承了可读流Readable和可写流Writable,并且没有定义其他的API,如图1所示:

scale一般用于开发什么(作为前端你一定要搞清楚)(1)

图1

也就是说它既可以当做可读流使用也可以当做可写流使用!

scale一般用于开发什么(作为前端你一定要搞清楚)(2)

图2

如图2所示,readable读入了5、4、3、2、1,writable1作为可写流将它们依次消费,同时writable1也作为可读流依次将10、9、8、7、6读入,由writable2作为可写流消费,这里writable1和writable2都是Duplex流,所以Duplex流是可以代替readable和writable使用的!

Transform流

这个流主要继承自Duplex流,所以它也可以同时当做可读流和可写流,通过参数自定义_transform方法和_flush方法,并且transform流自身实现了一个_write方法和_read方法,如图3所示:

scale一般用于开发什么(作为前端你一定要搞清楚)(3)

图3

先看一个简单的demo如下:

scale一般用于开发什么(作为前端你一定要搞清楚)(4)

图4

图4中的transform流被当做了可写流,并且在自定义的transform方法中可以消费上游传下来的数据,我们回想一下之前可读流writable是在_write方法中消费数据的,那么此处transform方法和_write方法是有什么关联吗?

scale一般用于开发什么(作为前端你一定要搞清楚)(5)

图5

通过源码,我们可以发现_write方法内部调用了transform方法,这样就通了,如图5所示!

Transform流核心能力是把处理之后的数据自动存入到自己的可读流缓存区,此时就是自动将自己从可写流转别为可读流,此处的玄机就在next方法!

scale一般用于开发什么(作为前端你一定要搞清楚)(6)

图6

如图6,我们把之前的next方法再封装一层,除了执行之前的next方法外,还把消费后的数据通过push方法存入自己的可读流缓存区,此处Transform流即是一个可读流也是一个可写流!

scale一般用于开发什么(作为前端你一定要搞清楚)(7)

图7

如图7中,我们再pipe一个可写流,你会发现,第一次读入的是0、1、2、4.....,在transform中处理一次(加一个‘1’字符串),此时最后的可写流会消费上游transform流传下去的数据。

另外,当transform流作为可写流时,消费完其可写流缓存区的数据时会触发一个prefinish事件,来通知用户是否还需要额外向自己push数据(此处是把自己当做可读流),如下图所示:

scale一般用于开发什么(作为前端你一定要搞清楚)(8)

图8

从图8中就可以看出来_flush方法的作用,可以额外追加数据,如下图,最后额外追加了数据‘end’。

scale一般用于开发什么(作为前端你一定要搞清楚)(9)

图9

总结

这篇文章主要分析了Transform流的特点,它和Duplex流一样,既能当做可读流也能当做可写流,不同的是前者可以自动将自己从可写流转化为可读流,而后者不具备这样的能力(当然可以自己在_write方法中开发这样的逻辑)!前面还提到一个流PassThrough,其实它就是Transform流,只是换了个名字而已!下一篇我们讨论一下如何写gulp插件,它就是对Transform流的实际应用!

喜欢我的文章就关注我吧,有问题可以发表评论,我们一起学习,共同成长!

,