web-dev-qa-db-fra.com

_read () n'est pas implémenté sur le flux lisible

Cette question est de savoir comment réellement implémenter la méthode de lecture d'un flux lisible.

J'ai cette implémentation d'un flux lisible:

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

Je reçois cette erreur

events.js: 136 lanceurs; // Événement "erreur" non géré ^

Erreur [ERR_STREAM_READ_NOT_IMPLEMENTED]: _read () n'est pas implémenté à Readable._read (_stream_readable.js: 554: 22) à Readable.read (_stream_readable.js: 445: 10) à resume_ (_stream_readable.js: 825: 12) à _callback (internal/process/next_tick.js: 138: 11) sur process._tickCallback (internal/process/next_tick.js: 180: 9) sur Function.Module.runMain (module.js: 684: 11) au démarrage (bootstrap_node. js: 191: 16) sur bootstrap_node.js: 613: 3

La raison pour laquelle l'erreur se produit est évidente, nous devons le faire:

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

Je ne comprends pas vraiment comment implémenter la méthode de lecture.

La seule chose qui fonctionne est d'appeler

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

si j'essaie de faire quelque chose comme ça:

   this.readableStream = new Readable({
          read(size) {
            this.Push('foo');   // call Push here!
            return true;
          }
     });

alors rien ne se passe - rien ne sort du lisible!

En outre, ces articles indiquent que vous n'avez pas besoin d'implémenter la méthode de lecture:

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

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

Ma question est - pourquoi l'appel de Push à l'intérieur de la méthode de lecture ne fait rien? La seule chose qui fonctionne pour moi est d'appeler readable.Push () ailleurs.

10
Alexander Mills

pourquoi l'appel de Push dans la méthode de lecture ne fait rien? La seule chose qui fonctionne pour moi est d'appeler readable.Push () ailleurs.

Je pense que c'est parce que vous ne le consommez pas, vous devez le diriger vers un flux inscriptible (par exemple stdout) ou simplement le consommer via un événement 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());
});

Les deux devraient imprimer 5 fois foo (ils sont cependant légèrement différents). Lequel vous devez utiliser dépend de ce que vous essayez d'accomplir.

En outre, ces articles indiquent que vous n'avez pas besoin d'implémenter la méthode de lecture:

Vous pourriez ne pas en avoir besoin, cela devrait fonctionner:

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)

Dans ce cas, vous ne pouvez pas le capturer via l'événement data. De plus, cette méthode n'est pas très utile et pas efficace, je dirais, nous poussons simplement toutes les données dans le flux à la fois (si elles sont volumineuses, tout sera en mémoire), puis nous les consommons.

5
Antonio Val

Implémentez le _read méthode après l'initialisation de votre ReadableStream:

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

De la documentation:

readable._read:

"Lorsque readable._read () est appelé, si des données sont disponibles à partir de la ressource, l'implémentation doit commencer à pousser ces données dans la file d'attente de lecture en utilisant la méthode this.Push (dataChunk). link "

lisible.Pousser:

"La méthode readable.Push () est destinée à être appelée uniquement par les implémenteurs Readable, et uniquement à partir de la méthode readable._read (). link "

J'espère que ça aide :)

1
i474232898