流是 Node.js 中处理数据的一种高效机制。它们允许你以连续的、非阻塞的方式处理数据,非常适合于处理大量数据或需要实时处理的数据。
创建可读流
可读流允许你从源中读取数据。你可以通过继承 stream.Readable 类来创建一个可读流。以下是一个简单的例子:
// www.javascriptcn.com code example
const { Readable } = require('stream');
class MyReadableStream extends Readable {
constructor(options) {
super(options);
this.data = ['Hello', 'World'];
this.index = 0;
}
_read() {
if (this.index === this.data.length) {
this.push(null); // 结束读取
} else {
let chunk = this.data[this.index++];
this.push(chunk + '\n');
}
}
}
const myStream = new MyReadableStream();
myStream.on('data', (chunk) => console.log(`Received: ${chunk}`));在这个例子中,我们定义了一个名为 MyReadableStream 的类,该类继承自 Readable 类。我们覆写了 _read() 方法,该方法会在内部调用时被触发,用来提供数据给流。当没有更多的数据可供读取时,我们推送一个 null 来结束读取过程。
创建可写流
可写流允许你向目的地写入数据。你可以通过继承 stream.Writable 类来创建一个可写流。以下是一个简单的例子:
// www.javascriptcn.com code example
const { Writable } = require('stream');
class MyWritableStream extends Writable {
constructor(options) {
super(options);
}
_write(chunk, encoding, callback) {
console.log(`Writing: ${chunk.toString()}`);
callback(); // 通知流数据已写入
}
}
const myWritableStream = new MyWritableStream();
myWritableStream.write('Hello'); // 输出: Writing: Hello
myWritableStream.write('World'); // 输出: Writing: World
myWritableStream.end(); // 结束写入在这个例子中,我们定义了一个名为 MyWritableStream 的类,该类继承自 Writable 类。我们覆写了 _write() 方法,该方法会在内部调用时被触发,用来接收和处理传入的数据。当数据成功写入后,我们需要调用 callback() 来通知流数据已处理完毕。
创建双向流
双向流允许你同时进行读写操作。你可以通过继承 stream.Duplex 或 stream.Transform 类来创建一个双向流。以下是一个简单的例子:
// www.javascriptcn.com code example
const { Transform } = require('stream');
class MyDuplexStream extends Transform {
constructor(options) {
super(options);
}
_transform(chunk, encoding, callback) {
const transformedChunk = chunk.toString().toUpperCase();
this.push(transformedChunk);
callback();
}
}
const myDuplexStream = new MyDuplexStream();
myDuplexStream.write('hello'); // 输出: HELLO
myDuplexStream.write('world'); // 输出: WORLD
myDuplexStream.end();在这个例子中,我们定义了一个名为 MyDuplexStream 的类,该类继承自 Transform 类。我们覆写了 _transform() 方法,该方法会在内部调用时被触发,用来接收传入的数据并转换它。转换后的数据会被推送到输出流中。当数据成功处理后,我们需要调用 callback() 来通知流数据已处理完毕。
创建管道流
管道流是一种将多个流连接在一起的方法,以便数据可以按顺序通过这些流进行处理。以下是一个简单的例子:
// www.javascriptcn.com code example
const { Readable, Writable } = require('stream');
const readableStream = new Readable({
read() {
this.push('Hello');
this.push('World');
this.push(null); // 结束读取
}
});
const writableStream = new Writable({
write(chunk, encoding, callback) {
console.log(`Writing: ${chunk.toString()}`);
callback();
}
});
readableStream.pipe(writableStream);在这个例子中,我们创建了一个可读流和一个可写流,并使用 pipe() 方法将它们连接在一起。这使得可读流中的数据会自动传递到可写流中进行处理。
通过以上几个示例,你可以看到 Node.js 中流的强大功能以及如何灵活地使用它们来处理数据。流不仅可以提高数据处理效率,还能帮助你构建更加健壮和高效的 Node.js 应用程序。