_read()未在可读流上实现

时间:2018-03-16 09:53:57

标签: node.js node-streams nodejs-stream

这个问题是如何真正实现可读流的读取方法。

我有一个可读流的实现:

import {Readable} from "stream";
this.readableStream = new Readable();

我收到此错误

  

events.js:136         扔掉//未处理的错误'事件         ^

     

错误[ERR_STREAM_READ_NOT_IMPLEMENTED]:_read()未实现       在Readable._read(_stream_readable.js:554:22)       在Readable.read(_stream_readable.js:445:10)       在resume_(_stream_readable.js:825:12)       at _combinedTickCallback(internal / process / next_tick.js:138:11)       at process._tickCallback(internal / process / next_tick.js:180:9)       在Function.Module.runMain(module.js:684:11)       在启动时(bootstrap_node.js:191:16)       在bootstrap_node.js:613:3

错误发生的原因很明显,我们需要这样做:

  this.readableStream = new Readable({
      read(size) {
        return true;
      }
    });

我真的不懂如何实现read方法。

唯一有效的方法就是调用

this.readableStream.push('some string or buffer');

如果我尝试做这样的事情:

   this.readableStream = new Readable({
          read(size) {
            this.push('foo');   // call push here!
            return true;
          }
     });
然后没有任何反应 - 没有任何东西可读!

此外,这些文章说您不需要实现读取方法:

https://github.com/substack/stream-handbook#creating-a-readable-stream

https://medium.freecodecamp.org/node-js-streams-everything-you-need-to-know-c9141306be93

我的问题是 - 为什么在read方法中调用push什么都不做?唯一对我有用的就是在其他地方调用readable.push()。

3 个答案:

答案 0 :(得分:3)

  

为什么在read方法中调用push什么都不做?唯一对我有用的就是在其他地方调用readable.push()。

我认为这是因为你没有消耗它,你需要将它传递给可写流(例如stdout)或者只是通过data事件来消费它:

const { Readable } = require("stream");

let count = 0;
const readableStream = new Readable({
    read(size) {
        this.push('foo');
        if (count === 5) this.push(null);
        count++;
    }
});

// piping
readableStream.pipe(process.stdout)

// through the data event
readableStream.on('data', (chunk) => {
  console.log(chunk.toString());
});

它们都应该打印5次foo(虽然它们略有不同)。你应该使用哪一个取决于你想要完成的任务。

  

此外,这些文章说你不需要实现read方法:

你可能不需要它,这应该有效:

const { Readable } = require("stream");

const readableStream = new Readable();

for (let i = 0; i <= 5; i++) {
    readableStream.push('foo');
}
readableStream.push(null);

readableStream.pipe(process.stdout)

在这种情况下,您无法通过data事件捕获它。此外,这种方式不是非常有用而且效率不高我会说,我们只是立即推送流中的所有数据(如果它的大部分都将在内存中),然后消耗它。

答案 1 :(得分:1)

在ReadableStream初始化后实施_read方法:

import {Readable} from "stream";
this.readableStream = new Readable();
this.readableStream.read = function () {};

答案 2 :(得分:1)

摘自文档:

可读。_read:

“调用read..read()时,如果资源中有可用数据,则实现应开始使用this.push(dataChunk)方法将数据推入读取队列。link

可读。push:

“只有可读取的实现者才能调用可读.push()方法,并且只能从read..read()方法内部调用。link

希望它会有所帮助:)