Node.JS - 需要帮助理解本地流

时间:2017-02-04 18:05:43

标签: javascript node.js ecmascript-6

我试图了解流的本地实现是如何工作的。这是代码:



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

有关

感谢任何帮助。

1 个答案:

答案 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');
});