Javascript 单独读/写数据流与双工流的区别?

Javascript 单独读/写数据流与双工流的区别?,javascript,node.js,node-streams,Javascript,Node.js,Node Streams,假设我们通过从stream类继承来创建自己的自定义可读写流。在第一个场景中,我们使用可读的和可写的类: const Stream=require(“流”); const readableStream=new Stream.Readable(); readableStream.\u read=(大小)=>{ for(设i=1;i{ log(“writeableStream”,chunk.toString()); next(); }; readableStream.pipe(可写流); 在第二个场

假设我们通过从stream类继承来创建自己的自定义可读写流。在第一个场景中,我们使用
可读的
可写的
类:

const Stream=require(“流”);
const readableStream=new Stream.Readable();
readableStream.\u read=(大小)=>{
for(设i=1;i<10;i++){
readableStream.push(`${i},`);
}
readableStream.push(null);
};
const writeableStream=new Stream.writeable();
writeableStream.\u write=(块、编码、下一步)=>{
log(“writeableStream”,chunk.toString());
next();
};
readableStream.pipe(可写流);
在第二个场景中,我们使用Duplex类(从可读/可写类继承):

const{Duplex}=require(“流”);
const myDuplexStream=new duplexstream();
myDuplexStream.\u读取=(大小)=>{
for(设i=1;i<10;i++){
push(`${i},`);
}
myDuplexStream.push(空);
};
myDuplexStream.\u write=(区块、编码、下一步)=>{
if(Buffer.isBuffer(chunk)){
chunk=chunk.toString();
}
log(“写操作”,区块);
};
myDuplexStream.pipe(myDuplexStream);//我想这是不可能的,但我们可以使用一个简单的“可读”事件。

这两个实现实际上相等吗?

不,它们不相同。

(A) 第一个示例显示了一个场景,其中整数被推送到可写缓冲区,该缓冲区通过管道将其数据传输到可写接收器。即:

  • 整数被推送到可读缓冲区
  • 可读管道将数据传输到可写缓冲区
  • 写入流将控制台记录数据
  • (B) 而第二个示例显示了一个奇怪的场景,即通过管道传输到双工的数据被记录到控制台。并且,与任何输入无关,每次其他流调用双工上的read()时,一些整数被推送到可读缓冲区。即:

  • (某些未知源必须向双工写入/管道数据)
  • 双工控制台记录流式输入
  • (没有数据从可写双工转发到可读双工,而是在后续可写调用read()时将整数列表推送到可读缓冲区。)
  • 当可写流在双工上调用read()时,它将整数1-9推送到可读缓冲区,以便可写流使用。然后它将关闭双工的可读端(由于
    推送(null)
  • 双工的可写部分处理传入数据,而可读部分提供传出数据。(B) 似乎混淆了duplex类中可读写的顺序

    OP的双工示例可能是:

    const{Duplex}=require(“流”);
    const myDuplexStream=new duplexstream();
    myDuplexStream.chunkProcessingBuffer=[]
    myDuplexStream.\u write=(区块、编码、下一步)=>{
    log(“这是我传入的块:”,chunk.toString());
    //通常,在将该块推送到可读接口之前,会以某种方式对其进行处理
    chunkProcessingBuffer.push(chunk);
    next();
    };
    myDuplexStream.\u读取=(大小)=>{
    //可读接口通常会在每次调用read()时推送多个块
    log(“这是我的传出区块:”,chunk.toString());
    myDuplexStream.push(chunkProcessingBuffer.shift());
    };
    const readableStream=new Stream.Readable();
    readableStream.\u read=(大小)=>{
    for(设i=1;i<10;i++){
    readableStream.push(`${i},`);
    }
    readableStream.push(null);
    };
    const writeableStream=new Stream.writeable();
    writeableStream.\u write=(块、编码、下一步)=>{
    log(“writeableStream”,chunk.toString());
    next();
    };
    readableStream.pipe(myDuplexStream).pipe(writableStream)
    
    感谢您抽出时间来写这篇文章!您能详细说明一下“
    //可读接口通常会在每次调用read()时推送多个块”
    为什么吗?很乐意提供帮助。让我举一个例子来解释;readable通常会从大数据源读取多个数据块。stream.writeable最初将在可读对象上调用read()一次,如果writeable可以以与可读对象相同的频率(或更快的速度)处理数据,则read()函数将只调用一次。然而,可读性越快,可读性越有可能填满可写的缓冲区,这反过来会触发“背压”,并导致可写的在准备好接收更多数据后调用read()。