[英]Node duplex stream doesn't actually emit data when read
我正在研究最終將用於 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);
導致進程剛剛結束。 所以我想我對我應該在_read
方法中做什么感到有點困惑。
OP提供的代碼的一些觀察:
read()
返回的鍵的迭代器是在設置任何鍵之前生成的,在: this.entries = this.values.entries();
. 因此,調用 read() 永遠不會產生輸出。可以使用內置的Transform (docs)構造函數簡化雙工實現。 轉換構造函數非常適合存儲轉發場景。
這是如何在這種情況下應用流轉換的示例。 請注意, pipeline()
函數不是必需的,並且已在此示例中用於簡化等待可讀對象發出其所有數據的過程:
const { Writable, Readable, Transform, pipeline } = require('stream');
class StorageStream extends Transform {
constructor() {
super({
objectMode: true
})
this.values = new Map();
}
_transform(data, encoding, next) {
const { key, value } = data;
this.values.set(key, value);
console.log(`Setting Map key ${key} := ${value}`)
next(null, data);
}
}
(async ()=>{
await new Promise( resolve => {
pipeline(
new Readable({
objectMode: true,
read(){
this.push( { key: 'foo', value: 'bar' } );
this.push( null );
}
}),
new StorageStream(),
new Writable({
objectMode: true,
write( chunk, encoding, next ){
console.log("propagated:", chunk);
next();
}
}),
(error) => {
if( error ){
reject( error );
}
else {
resolve();
}
}
);
});
})()
.catch( console.error );
這會產生以下輸出
> Setting Map key foo := bar
> propagated: { key: 'foo', value: 'bar' }
並且可以用作
kvstream.pipe(new StorageStream()).pipe(logger);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.