双工流(Duplex Stream)是 Node.js 中的一种流类型,它同时具有读取和写入功能。这意味着你可以从流中读取数据,也可以向流中写入数据。双工流通常用于处理需要双向通信的场景,例如网络通信、文件传输等。
创建双工流
创建双工流主要通过继承 stream.Duplex 类来实现。这个类提供了所有必要的方法和属性,使我们能够轻松地创建一个自定义的双工流。
示例代码
// www.javascriptcn.com code example
const { Duplex } = require('stream');
class MyDuplexStream extends Duplex {
constructor(options) {
super(options);
}
_read(size) {
// 实现读取逻辑
this.push(null); // 结束读取
}
_write(chunk, encoding, callback) {
// 实现写入逻辑
callback();
}
}
// 使用自定义的双工流
const myStream = new MyDuplexStream();
myStream.on('data', (chunk) => {
console.log('收到数据:', chunk.toString());
});
myStream.write('Hello, World!');在这个示例中,我们创建了一个名为 MyDuplexStream 的双工流类,并实现了 _read 和 _write 方法。这两个方法分别用于实现读取和写入操作。当向流中写入数据时,会触发 _write 方法;当从流中读取数据时,会触发 _read 方法。
双工流的使用场景
双工流在许多场景下都非常有用,尤其是在需要进行双向通信的情况下。以下是一些常见的使用场景:
- TCP/IP 通信:在网络通信中,客户端和服务器之间的数据交换通常需要双向通信,这时可以使用双工流。
- 文件传输:在传输文件的过程中,可能需要同时读取和写入文件,这时也可以使用双工流。
- 管道处理:在处理数据流时,可能需要对数据进行过滤或转换,这时可以将多个读取和写入操作组合在一起形成一个双工流。
流控制
双工流同样支持流控制,这意味着在某些情况下,我们可以暂停或恢复数据的流动。这有助于防止内存溢出或处理大量数据时的数据丢失。
暂停和恢复
pause():暂停数据流动。resume():恢复数据流动。
示例代码
// www.javascriptcn.com code example
const { Duplex } = require('stream');
class MyDuplexStream extends Duplex {
constructor(options) {
super(options);
}
_read(size) {
// 实现读取逻辑
this.push(null); // 结束读取
}
_write(chunk, encoding, callback) {
// 实现写入逻辑
console.log('写入数据:', chunk.toString());
callback();
}
}
// 使用自定义的双工流
const myStream = new MyDuplexStream();
myStream.pause(); // 暂停数据流动
setTimeout(() => {
myStream.resume(); // 恢复数据流动
}, 5000);在这个示例中,我们创建了一个名为 MyDuplexStream 的双工流类,并在一段时间后恢复了数据流动。通过调用 pause() 和 resume() 方法,我们可以灵活地控制数据的流动。
错误处理
在处理流时,错误处理非常重要。双工流通过 emit 方法来发出错误事件,并且可以通过监听这些事件来捕获和处理错误。
示例代码
// www.javascriptcn.com code example
const { Duplex } = require('stream');
class MyDuplexStream extends Duplex {
constructor(options) {
super(options);
}
_read(size) {
// 实现读取逻辑
this.push(null); // 结束读取
}
_write(chunk, encoding, callback) {
// 实现写入逻辑
if (chunk.toString().includes('error')) {
this.emit('error', new Error('错误的数据'));
}
callback();
}
}
// 使用自定义的双工流
const myStream = new MyDuplexStream();
myStream.on('error', (err) => {
console.error('捕获到错误:', err.message);
});
myStream.write('normal data');
myStream.write('error data'); // 触发错误事件在这个示例中,我们在 _write 方法中检查数据是否包含特定字符串,并在发现错误数据时发出一个错误事件。然后,我们通过监听 error 事件来捕获并处理这些错误。
总结
双工流是 Node.js 中非常强大的工具,它使得处理双向数据流变得简单而高效。通过继承 stream.Duplex 类,我们可以轻松地创建自定义的双工流,并利用其提供的方法和属性来实现复杂的流处理逻辑。希望本章的内容能帮助你更好地理解和应用双工流。