Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 节点双工流不';当读取数据时,实际上不会发出数据_Javascript_Node.js_Duplex_Node Streams - Fatal编程技术网

Javascript 节点双工流不';当读取数据时,实际上不会发出数据

Javascript 节点双工流不';当读取数据时,实际上不会发出数据,javascript,node.js,duplex,node-streams,Javascript,Node.js,Duplex,Node Streams,我正在研究一种数据接收器,它最终将用于nodejs中的键值对象流 我偶然发现了双工流,并开始玩他们一点让我的脚湿,但我尝试的一切似乎都不起作用 目前,我有一个双工流: class StorageStream extends stream.Duplex { constructor() { super({ objectMode: true }) this.values = new Map(); this.entries = this.values.e

我正在研究一种数据接收器,它最终将用于nodejs中的键值对象流

我偶然发现了双工流,并开始玩他们一点让我的脚湿,但我尝试的一切似乎都不起作用

目前,我有一个双工流:

class StorageStream extends stream.Duplex {
  constructor() {
    super({
      objectMode: true
    })

    this.values = new Map();
    this.entries = this.values.entries();
  }

  _write(data, encoding, next) {
    const { key, value } = data;

    this.values.set(key, value);

    next();
  }

  _read() {
    const next = this.entries.next();

    if (next.value) {
      this.push(next.value);
    }
  }
}
这是一个超级做作的示例,但本质上,当我向这个流写入时,它应该将键和值存储在映射中,当我从这个流中读取时,它应该开始从映射中读取并将它们传递到流中。但是,这不起作用,基本上做了以下工作

const kvstream = createKVStreamSomeHow(); // a basic, readable stream with KV Pairs

const logger = createLoggerStreamSomeHow(); // writable stream, logs the data coming through

const storage = new StorageStream();

kvstream.pipe(storage).pipe(logger);

导致进程刚刚结束。所以我想我只是有点困惑,我应该在
\u read
方法中做些什么。

从OP提供的代码中观察到一些情况:

  • 在设置任何键之前,在
    this.entries=this.values.entries()中生成循环遍历
    read()
    返回的键的迭代器。因此,调用read()永远不会产生输出
  • 如果在映射中设置了一个新的键,则不会将其推送到读取缓冲区,以供后续的可写处理
  • 使用内置构造函数可以简化双工实现。转换构造函数非常适合存储和转发场景

    这是一个在这种情况下如何应用流转换的示例。请注意,
    pipeline()
    函数不是必需的,并且在本例中用于简化等待readable发出其所有数据的过程:

    const{Writable,Readable,Transform,pipeline}=require('stream');
    类StorageStream扩展了转换{
    构造函数(){
    超级({
    objectMode:true
    })
    this.values=新映射();
    }
    _转换(数据、编码、下一步){
    常量{key,value}=数据;
    此.values.set(键,值);
    log(`Setting Map key${key}:=${value}`)
    下一步(空,数据);
    }
    }
    (异步()=>{
    等待新的承诺(解决=>{
    管道(
    新可读({
    objectMode:true,
    读(){
    push({key:'foo',value:'bar'});
    这个.push(null);
    }
    }),
    新建StorageStream(),
    新可写({
    objectMode:true,
    写入(块、编码、下一步){
    log(“已传播:”,块);
    next();
    }
    }),
    (错误)=>{
    如果(错误){
    拒绝(错误);
    }
    否则{
    解决();
    }
    }
    );
    });
    })()
    .catch(console.error);
    
    这将产生以下输出

    > Setting Map key foo := bar
    > propagated: { key: 'foo', value: 'bar' }
    
    并且可以用作

    kvstream.pipe(new StorageStream()).pipe(logger);