_read() не реализован в читаемом потоке

Этот вопрос заключается в том, как на самом деле реализовать метод чтения читаемого потока.

У меня есть эта реализация читаемого потока:

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) в резюме_ (_stream_readable.js:825:12) в _combinedTickCallback (internal/process/next_tick.js:138:11) в process._tickCallback (внутренний/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;
      }
    });

Я действительно не понимаю, как реализовать метод чтения.

Единственное, что работает, это просто позвонить

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

Мой вопрос: почему вызов push внутри метода чтения ничего не делает? Единственное, что работает для меня, это просто вызов readable.push() в другом месте.


person Alexander Mills    schedule 16.03.2018    source источник


Ответы (3)


почему вызов push внутри метода чтения ничего не делает? Единственное, что работает для меня, это просто вызов readable.push() в другом месте.

Я думаю, это потому, что вы его не используете, вам нужно передать его в доступный для записи поток (например, стандартный вывод) или просто использовать его через событие 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 (хотя они немного отличаются). Какой из них вы должны использовать, зависит от того, чего вы пытаетесь достичь.

Кроме того, в этих статьях говорится, что вам не нужно реализовывать метод чтения:

Возможно, вам это не нужно, это должно работать:

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. Кроме того, этот способ не очень полезен и неэффективен, я бы сказал, мы просто помещаем все данные в поток сразу (если он большой, все будет в памяти), а затем потребляем его.

person Antonio Val    schedule 16.03.2018
comment
Я всегда пил его с readable.on('data', function(){}); - person Alexander Mills; 16.03.2018
comment
Я расширил объяснение, если вы хотите сделать это так, вам действительно нужно реализовать метод чтения! - person Antonio Val; 16.03.2018
comment
попробуйте ваш второй пример - он должен выдать ошибку о том, что вам нужно реализовать _read()... - person Alexander Mills; 16.03.2018
comment
У меня работает, вы закрываете его, нажимая null? - person Antonio Val; 16.03.2018

Из документации:

читаемый._read:

При вызове readable._read(), если данные доступны из ресурса, реализация должна начать помещать эти данные в очередь чтения, используя метод this.push(dataChunk). ссылка

readable.push:

Метод readable.push() предназначен для вызова только реализаторами Readable и только из метода readable._read(). ссылка

person i474232898    schedule 10.03.2019

Реализуйте метод _read после инициализации вашего ReadableStream:

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