callback per gestire il completamento della pipe


196

Sto usando il seguente codice node.js per scaricare documenti da alcuni URL e salvarli sul disco. Voglio essere informato su quando il documento viene scaricato. non ho visto alcun callback con pipe. Oppure, c'è qualche evento 'end' che può essere catturato al completamento del download?

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

Risposte:


302

I flussi sono in EventEmittermodo da poter ascoltare determinati eventi. Come hai detto, c'è un finishevento per richiesta (in precedenza end).

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

Per ulteriori informazioni su quali eventi sono disponibili, è possibile controllare la pagina di documentazione dello stream .


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

6
per me l'evento 'close', piuttosto che 'end' funzionar.on('close'), function () {...})
Judson

9
L'evento 'end' ora è 'finish' Eventi pipe: nodejs.org/api/stream.html#stream_event_finish
Pier-Luc Gendreau,

13
L'evento 'end' esiste ancora e viene utilizzato sui flussi leggibili. I flussi scrivibili usano 'finish'. Questo perché il flusso Transform è un mix di entrambi e deve differenziare gli eventi.
noderman

16
Questo thread è un buon riassunto di come funziona il flusso di nodi.
pomber


9

Snippet di codice per il piping del contenuto dal web via http (s) al filesystem. Come notato da @starbeamrainbowlabs, l'evento finishfunziona

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);
});

Il 'fine' funziona per me e 'fine' no. Grazie!
shaosh

1
in un caso particolare, il traguardo sembra sparare prima che arrivino tutti i byte previsti
Michael,

4

Ho trovato una soluzione un po 'diversa del mio problema in questo contesto. Vale la pena condividere.

La maggior parte dell'esempio crea readStreamsda file. Ma nel mio caso readStreamdeve essere creato da una JSONstringa proveniente da un pool di messaggi.

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 );

Invece di ascoltare "finish" hai due gestori per "close", forse era questo il motivo. L'evento "finish" funziona per me.
jowo,

3

Ecco una soluzione che gestisce gli errori nelle richieste e chiama un callback dopo la scrittura del file:

request(opts)
    .on('error', function(err){ return callback(err)})
    .pipe(fs.createWriteStream(filename))
    .on('finish', function (err) {
        return callback(err);
    });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.