流的理解 1
1:流(Stream)到底是什么?
流就是一系列的数据——就跟数组或者字符串一样。有一点不同,就是 stream 可能无法在一次性全部可用,且它们不需要与内存完全合槽。这么一来,stream 在处理大量数据,或者操作一个一次只给出一部分数据的数据源的时候显得格外有用。
其实,流不只是在操作大量数据的时候有用。它还为在代码中使用各种强大的组合类功能提供能力。例如,我们在 Linux 命令行中可以通过管道(pipe)来完成一些组合性的命令,在 Node.js 的流中也能实现。
2:掌握核心方法 readableStream.pipe(writableSrteam)
3:helloworld
process.stdin.pipe(process.stdout);
4:很多 Node.js 的内置模块都是基于流接口的:

其中有一些对象甚至是既可读又可写的,例如 TCP socket、zlib 以及 crypto 等。
值得注意的是上面说的一些对象也是彼此紧密联系的。例如 HTTP 响应在客户端中是一个可读流,而在服务端则是一个可写流。毕竟在 HTTP 场景中,我们在客户端侧是从相应对象(http.IncommingMessage)读取数据,而在服务端则是写入数据(http.ServerResponse)。
还需要注意的是,stdio 相应的流(stdin, stdout, stderr)在子进程中与主进程都是相反的流类型。这样一来主进程和子进程直接就可以方便地 pipe stdio 数据了。
Node.js 中的流有 4 种基本类型:Readable(可读流)、Writable(可写流)、Duplex(双工流)和 Transform(转换流)。
- 可读流是对于可被消耗的数据源的抽象。例如
fs.createReadStream方法; - 可写流是对于可被写入的数据目标的抽象。例如
fs.createWriteStream方法; - 双工流是可读流与可写流的集合体。例如 TCP socket;
- 转换流基本上就是一个双工流,只不过在读写的时候可以修改或者转化数据,例如
zlib.createGzip就将数据使用 gzip 压缩了。你可以将变形金刚流看成是一个函数,其中输入是可写流,而输出是一个可读流。
所有的流都是继承自 EventEmitter。也就是说,它们触发的事件可以用于读写数据。不过,我们也可以简单粗暴地用 pipe 来消费流数据。
5:自己实现流
// 可读流
const inStream = new Readable({
read(size) {
this.push(String.fromCharCode(this.currentCharCode++));
if (this.currentCharCode > 90) {
this.push(null);
}
}
});
inStream.currentCharCode = 65;
inStream.pipe(process.stdout);
// 可写流
const { Writable } = require('stream');
const outStream = new Writable({
write(chunk, encoding, callback) {
console.log(chunk.toString());
callback();
}
});
process.stdin.pipe(outStream);
// 双工流
const { Duplex } = require('stream');
const inoutStream = new Duplex({
write(chunk, encoding, callback) {
console.log(chunk.toString());
callback();
},
read(size) {
this.push(String.fromCharCode(this.currentCharCode++));
if (this.currentCharCode > 90) {
this.push(null);
}
}
});
inoutStream.currentCharCode = 65;
process.stdin.pipe(inoutStream).pipe(process.stdout);
// 转换流
const { Transform } = require('stream');
const upperCaseTr = new Transform({
transform(chunk, encoding, callback) {
this.push(chunk.toString().toUpperCase());
callback();
}
});
process.stdin.pipe(upperCaseTr).pipe(process.stdout);
6:导图


浙公网安备 33010602011771号