es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Nodejs, el flujo legible (Readable stream), no emite el evento ‘end’.

Creo un objeto Buffer y un flujo Readable, con el objetivo de que el flujo Readable consuma el objeto Buffer.

El código es así:

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

// creo un objeto Buffer y le asigno una longitud de 200 para agregar un texto largo
const buf = Buffer.alloc(200, 'este es un texto muuy largo..');


const readStream = (buf_data) => {
return new Readable({
  read(size){
    // Hago un push de los datos de fragmentos al flujo
    this.push(buf_data);

    // Aquí DEBE haber algo que haga `push(null)` y emita el evento 'end'
    // ¿¿¿???
  }
});
};

// Paso el objeto Buffer al flujo de lectura
read = readStream(buf);


// Se llama al evento 'data' para imprimir los fragmentos de los datos
read.on('data', (chunk) => {
  console.log('chnk:', chunk.toString());
});

// El evento 'end', actualmente no se emite y la lectura no se detiene.
read.on('end', (chunk) => {
 console.log('--fin--');
});

Cuando ejecuto la aplicación (node ), la aplicación sigue leyendo e imprimiendo el texto.

Debe haber una condición que pueda agregar en el método read() para hacer que se active el evento end.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para hacer que se active el evento end, necesitamos agregar una comprobación dentro del método read() para determinar si el búfer ha sido completamente leído. Si se ha leído todo el búfer, entonces podemos añadir null al flujo de datos, lo que activará el evento end. Aquí está el código modificado:

    const { Readable } = require('stream');
    
    // creamos un Buffer y asignamos 200 posiciones para agregar el texto largo
    const buf = Buffer.alloc(200, 'este es un teeeeeeeexto muy largo...');
    
    const readStream = (buf_data) => {
      return new Readable({
        read(size) {
          // calcular el tamaño restante del búfer
          const remainingSize = buf_data.length - this.pos;
    
          if (remainingSize <= 0) {
            // no hay más datos para leer, añadimos null para finalizar el flujo de datos
            this.push(null);
          } else {
            // agregar un fragmento de datos del búfer al flujo de datos
            const chunk = buf_data.slice(this.pos, this.pos + size);
            this.push(chunk);
            this.pos += chunk.length;
          }
        }
      })
    }
    
    // Pasamos el Buffer al flujo de datos legibles
    const read = readStream(buf)
    
    // el evento 'data' se llama para imprimir los datos del fragmento
    read.on('data', (chunk) => {
      console.log('chnk:', chunk.toString())
    })
    
    // el evento 'end', actualmente no se está emitiendo y la lectura no se detiene.
    read.on('end', () => {
     console.log('--end--')
    })
    

    En el código modificado, agregamos una propiedad pos al objeto del flujo de datos legibles que sigue la posición actual en el búfer. Dentro del método read(), calculamos el tamaño restante del búfer (remainingSize = buf_data.length - this.pos) y comprobamos si es mayor que 0. Si no lo es, entonces añadimos null al flujo de datos para activar el evento end.

    Si aún quedan datos en el búfer, hacemos un fragmento de datos del búfer y lo agregamos al flujo de datos, y aumentamos la propiedad pos en consecuencia. Ahora, cuando ejecutamos la aplicación, leerá el búfer y activará el evento end correctamente.

Comments are closed.