我正在研究一种数据接收器,该数据接收器最终将用于nodejs中的键值对象流。
我偶然发现了双工流,并开始与它们玩耍以弄湿自己的脚,但是我尝试的所有操作似乎都无效。
目前,我有以下双工流:
<div class="col-sm-9">
<select [formControlName]="i" type="text" class="form-control" [ngClass]="{'error-border': isSubmitted && mealType.errors}">
<option value="" disabled selected></option>
<option [ngValue]="meal.id" *ngFor="let meal of filteredMealTypes">{{meal.mealType}}</option>
</select>
</div>
这是一个SUPER CONTRIVED示例,但是从本质上讲,当我向该流写入内容时,它应该将键和值存储在Map中,而当我从该流中读取时,它应该开始从地图中读取并将它们向下传递。但是,此操作不起作用,基本上可以执行以下操作
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);
方法中应该做的事情有点困惑。
答案 0 :(得分:0)
OP提供的代码中的一些观察结果:
read()
中设置任何键之前,会生成循环this.entries = this.values.entries();
返回的键的迭代器。因此,调用read()永远不会产生输出。可以使用内置的Transform (docs)构造函数来简化双工实现。转换构造函数非常适合存储转发方案。
这是在这种情况下如何应用流Transform的示例。请注意,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);