你可能也在最初开始使用 Gulp 的时候就听说过:Gulp 是一个有关 Stream(数据流)的构建系统。这句话的意思是:
Gulp 本身使用了 Node 的 Stream。
Stream 如其名字所示的 “流” 那样,就像是工厂的流水线。你要加工一个产品,不用全部在一个位置完成,而是可以拆分成多道工序。产品从第一道工序开始,第一道工序完成后,输出然后流入第二道工序,然后再第三道工序… 一方面,大批量的产品需求也不用等到全部完工(这通常很久),而是可以完工一个就拿到一个。另一方面,复杂的加工过程被分割成一系列独立的工序,这些工序可以反复使用,还可以在需要的时候进行替换和重组。这就是 Stream 的理念。
Stream 在 Node 中的应用十分广泛,几乎所有 Node 程序都在某种程度上用到了 Stream。
Stream 有一个很基本的操作叫做管道(pipe)。Stream 是水流,而管道可以从一个流的输出口,接到另一个流的输入口,从而控制流向。如果用前面的流水线工序来说的话,就是连接工序的传输带了。
Node 的 Stream 有一个方法 pipe (),也就是管道操作对应的方法。它一般这样用:
src.pipe(dest)
其中 src 和 dest 都是 stream,分别代表源和目标。也就是说,流 src 的输出,将作为输入转到流 dest。此外,这个方法返回目标流(比如这里 .pipe (dest) 返回 dest),因此可以链式调用:
a.pipe(b).pipe(c).pipe(d)
Stream 的整个操作过程,都在内存中进行。因此,相比 Grunt,使用 Stream 的 Gulp 进行多步操作并不需要创建中间文件,可以省去额外的 src 和 dest。
Node 的 Stream 都是 Node 事件对象 EventEmitte 的实例,它们可以通过 .on() 添加事件侦听。
在现在的 Node 里,Stream 被分为 4 类,分别是 Readable(只读)、Writable(只写)、Duplex(双向)、 Transform(转换)。其中 Duplex 就是指可读可写,而 Transform 也是 Duplex,只不过输出是由输入计算得到的,因此算作 Duplex 的特例。
Readable Stream 和 Writable Stream 分别有不同的 API 及事件(例如 readable.read () 和 writable.write () ),Duplex Stream 和 Transform Stream 因为是可读可写,因此拥有前两者的全部特性。
虽然 Node 中可以通过 require (“stream”) 引用 Stream,但比较少会需要这样直接使用。大部分情况下,我们用的是 Stream Consumers,也就是具有 Stream 特性的各种子类。