我试图了解流的本地实现是如何工作的。这是代码:
const Stream = require('stream');
// define a custom class to read my data into the stream
class SourceWrapper extends Stream.Readable {
constructor(opt, content) {
super(opt);
this.content = content;
this.len = content.length;
this.index = 0;
}
_read() {
let i = this.index++;
if (i >= this.len)
this.push(null);
else {
this.push(this.content[i]);
}
}
}
// generate some data
const arr = (new Array(10000000)).fill(1);
// declare the streams
const firstStream = new SourceWrapper({objectMode: true}, arr);
const transform = (x, enc, next) => next(undefined, x * Math.random(x, 10));
const firstMapStream = new Stream.Transform({objectMode: true});
firstMapStream._transform = transform;
const secondMapStream = new Stream.Transform({objectMode: true});
secondMapStream._transform = transform;
// create a promise to measure execution time
const start = new Date();
new Promise((resolve, reject) => {
firstStream
.pipe(firstMapStream)
.pipe(secondMapStream)
.on('finish', () => resolve(new Date()));
})
.then((end) => console.log('execTime', end - start));

问题在于它适用于小型数据集(即[1,2,3,4]
),但似乎在大型数据集上运行后很快终止。
我错过了什么?它是否与objectMode
?
感谢任何帮助。
答案 0 :(得分:1)
原因是有人应该使用绑定data
事件侦听器从流中读取数据。我已经重写了您的代码,以便清楚地了解问题。另外我修正了错误的索引计数,它跳过零索引。
'use strict';
const Stream = require('stream');
// define a custom class to read my data into the stream
class SourceWrapper extends Stream.Readable {
constructor(opt, content) {
super(opt);
this.content = content;
this.len = content.length;
this.index = 0;
}
_read() {
let i = this.index;
if (i >= this.len) {
this.push(null);
} else {
this.push(this.content[i]);
}
this.index++;
}
}
const transform = (x, enc, next) => next(undefined, x * Math.random(x, 10));
const transform1 = new Stream.Transform({objectMode: true});
transform1._transform = transform;
const transform2 = new Stream.Transform({objectMode: true});
transform2._transform = transform;
const write = new Stream.Writable({
objectMode: true,
write(value, enc, next) {
// Do something like writing...
next();
}
});
// generate some data
const arr = (new Array(1000000)).fill(1);
const read = new SourceWrapper({objectMode: true}, arr);
new Promise((resolve, reject) => {
read
.pipe(transform1)
.pipe(transform2)
.pipe(write)
.on('finish', () => {
resolve();
});
})
.then(() => {
console.log('Done');
});