最近总是听见 liu 这个东西啊,比如 liu 翔低调宣布新恋情啦、 liu 强冬告白奶茶啦、微软停止支持 IE liu 览器啦,最近我们的淘宝前端夜校讲师也提到了 liu (流)的运用。
在 Unix 系统中流就是一个很常见也很重要的概念。
Unix 的哲学:一个程序只做一件事,并做好。程序要能协作。程序要能处理文本流,因为这是最通用的接口。
– Douglas McIlroy
还记得在你刚开始学习编程,尤其是学 C 语言会接触到文件流的概念。不限于文件系统的文件,还有输入输出的逻辑文件,因为在 C 中所有流均以文件的形式出现,今天肯定不是说 C , 在以异步 IO 高效著称 Node.js 中,流也是一个值得深入理解的概念。
在前端开发中,你可能见过这样的构建代码。
1 2 3 4 |
gulp.task('images', ['clean'], function() { return gulp.src(paths.images) .pipe(gulp.dest('build/img')); }); |
那么什么是流?
用术语说流是对输入输出设备的抽象。以程序的角度说,流是具有方向的数据。在 Unix 系统中,我们使用符号|
来实现流。
在 Node.js 中有个 stream 模块,它是一个抽象类。它的抽象接口被很多常见对象实现,比如常见的 request response
按照流动方向,stream 流分为 4 种,Readable,writable,Duplex streams 和 Transform streams。后两种可以理解为可读可写流的组合,所以优先理解可读可写流。
可以直接使用 stream_readable 创建一个流
1 2 3 4 5 6 7 |
var Readable = require('stream').Readable; var rs = new Readable; rs.push('beep '); rs.push('boop '); rs.push('null\n'); rs.push(null); rs.pipe(process.stdout); |
运行代码
1 2 |
$ node readable.js beep boop null |
数据被原样输出了,nul l 表示输出结束。
流的模式
那么如何才能协调输入输出呢,实际上,readable 流的数据会存在缓存中,直到有个流来消耗这些数据。简单的说,就是要多少,就尽量给多少。
readable stream 有个待实现接口 _read(size)
readable._read(size)
- size Number Number of bytes to read asynchronously
可以通过这个接口来验证流的工作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
var Readable = require('stream').Readable; var rs = Readable(); var c = 97 - 1; rs._read = function () { if (c >= 'z'.charCodeAt(0)) return rs.push(null); //设置延时,有个直观感受 setTimeout(function () { rs.push(String.fromCharCode(++c)); }, 200); }; rs.pipe(process.stdout); process.on('exit', function () { console.error('\n_read() called ' + (c - 97) + ' times'); }); process.stdout.on('error', process.exit); |
运行代码
1 2 3 |
$ node readable.js | head -c 5 abcde _read() called 5 times |
大约一秒后,5 个字符直接输出了。
所以其实 readable 流是到了一定的水位,才会将这些数据吐出来。
你可能已经感觉到了,可读流一天到晚就处在两种状态:我吐了、我不吐了!
事实上确实是这样, Node.js 文档对流状态的说明。
Readable streams have two “modes”: a flowing mode and a paused mode.
流的两种状态分别称为流模式和暂停模式
进入流模式有三种方法
- Adding a ‘data’ event handler to listen for data.
- Calling the resume() method to explicitly open the flow.
- Calling the pipe() method to send the data to a Writable.
也有两种方法暂停
- If there are no pipe destinations, by calling the pause() method.
- If there are pipe destinations, by removing any ‘data’ event handlers, and removing all pipe destinations by calling the unpipe() method.
流的常见应用
一个流的日常任务:
举个栗子:服务器要读取文件返回给客户端:
1 ۬的淘宝前端夜校讲师也提到了 liu (流)的运用。
在 Unix 系统中流就是一个很常见也很重要的概念。
还记得在你刚开始学习编程,尤其是学 C 语言会接触到文件流的概念。不限于文件系统的文件,还有输入输出的逻辑文件,因为在 C 中所有流均以文件的形式出现,今天肯定不是说 C , 在以异步 IO 高效著称 Node.js 中,流也是一个值得深入理解的概念。 在前端开发中,你可能见过这样的构建代码。
那么什么是流?用术语说流是对输入输出设备的抽象。以程序的角度说,流是具有方向的数据。在 Unix 系统中,我们使用符号 按照流动方向,stream 流分为 4 种,Readable,writable,Duplex streams 和 Transform streams。后两种可以理解为可读可写流的组合,所以优先理解可读可写流。 可以直接使用 stream_readable 创建一个流
运行代码
数据被原样输出了,nul l 表示输出结束。 流的模式那么如何才能协调输入输出呢,实际上,readable 流的数据会存在缓存中,直到有个流来消耗这些数据。简单的说,就是要多少,就尽量给多少。 readable stream 有个待实现接口 _read(size)
可以通过这个接口来验证流的工作
运行代码
大约一秒后,5 个字符直接输出了。 你可能已经感觉到了,可读流一天到晚就处在两种状态:我吐了、我不吐了! 事实上确实是这样, Node.js 文档对流状态的说明。
流的两种状态分别称为流模式和暂停模式
也有两种方法暂停
流的常见应用一个流的日常任务: |