devolución de llamada para manejar la finalización de la tubería


196

Estoy usando el siguiente código node.js para descargar documentos de alguna url y guardarlo en el disco. Deseo recibir información sobre cuándo se descarga el documento. no he visto ninguna devolución de llamada con pipe.O, ¿hay algún evento de 'finalización' que pueda capturarse al finalizar la descarga?

request(some_url_doc).pipe(fs.createWriteStream('xyz.doc'));

Respuestas:


302

Las transmisiones son EventEmitters para que pueda escuchar ciertos eventos. Como dijiste, hay un finishevento para solicitar (previamente end).

 var stream = request(...).pipe(...);
 stream.on('finish', function () { ... });

Para obtener más información sobre qué eventos están disponibles, puede consultar la página de documentación de la transmisión .


12
var r = request(...).on("end",function(){/* CALLBACK */}).pipe(...);
— Denys Vitali

66
para mí, el evento 'cerrar', en lugar de 'finalizar' funcionar.on('close'), function () {...})
— Judson

9
El evento 'final' ahora es 'finalizar' Eventos de canalización
— Pier-Luc Gendreau

13
El evento 'final' todavía existe y se usa en transmisiones legibles. Las secuencias que se pueden escribir usan 'terminar'. Esto se debe a que el flujo Transformar es una mezcla de ambos y necesita diferenciar entre los eventos.
— Noderman

16
Este hilo es un buen resumen de cómo es trabajar con flujos de nodos.
— pomber


9

Fragmento de código para canalizar contenido de la web a través de http (s) al sistema de archivos. Como @starbeamrainbowlabs notó que el evento finishfunciona

var tmpFile = "/tmp/somefilename.doc";

var ws = fs.createWriteStream(tmpFile);
ws.on('finish', function() {
  // pipe done here, do something with file
});

var client = url.slice(0, 5) === 'https' ? https : http;
client.get(url, function(response) {
  return response.pipe(ws);
});

El "final" funciona para mí y el "final" no. ¡Gracias!
— shaosh

1
en un caso particular, el final parece estar disparando antes de que lleguen todos los bytes esperados
— Michael

4

Encontré una solución un poco diferente de mi problema con respecto a este contexto. Pensamiento que vale la pena compartir.

La mayor parte del ejemplo se crea readStreamsdesde un archivo. Pero en mi caso readStreamtiene que ser creado a partir de una JSONcadena proveniente de un grupo de mensajes.

var jsonStream = through2.obj(function(chunk, encoding, callback) {
                    this.push(JSON.stringify(chunk, null, 4) + '\n');
                    callback();
                });
// message.value --> value/text to write in write.txt 
jsonStream.write(JSON.parse(message.value));
var writeStream = sftp.createWriteStream("/path/to/write/write.txt");

//"close" event didn't work for me!
writeStream.on( 'close', function () {
    console.log( "- done!" );
    sftp.end();
    }
);

//"finish" event didn't work for me either!
writeStream.on( 'close', function () {
    console.log( "- done!"
        sftp.end();
        }
);

// finally this worked for me!
jsonStream.on('data', function(data) {
    var toString = Object.prototype.toString.call(data);
    console.log('type of data:', toString);
    console.log( "- file transferred" );
});

jsonStream.pipe( writeStream );

En lugar de escuchar "terminar" tienes dos controladores para "cerrar", tal vez esa fue la razón. El evento "terminar" funciona para mí.
— jowo

3

Aquí hay una solución que maneja los errores en las solicitudes y llama a una devolución de llamada después de escribir el archivo:

request(opts)
    .on('error', function(err){ return callback(err)})
    .pipe(fs.createWriteStream(filename))
    .on('finish', function (err) {
        return callback(err);
    });
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.