Rückruf zur Fertigstellung der Pipe


195

Ich verwende den folgenden node.js-Code, um Dokumente von einer URL herunterzuladen und auf der Festplatte zu speichern. Ich möchte darüber informiert werden, wann das Dokument heruntergeladen wird. Ich habe keinen Rückruf mit Pipe gesehen. Oder gibt es ein "End" -Ereignis, das nach Abschluss des Downloads erfasst werden kann?

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

Antworten:


301

Streams sind EventEmitters, damit Sie bestimmte Ereignisse anhören können. Wie Sie sagten, gibt es ein finishEreignis zur Anfrage (vorher end).

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

Weitere Informationen zu den verfügbaren Ereignissen finden Sie auf der Stream-Dokumentationsseite .


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

6
Für mich funktioniert das Ereignis "schließen" und nicht "beenden"r.on('close'), function () {...})
Judson


13
Das 'End'-Ereignis existiert noch und wird in lesbaren Streams verwendet. Beschreibbare Streams verwenden 'finish'. Dies liegt daran, dass der Transformationsstrom eine Mischung aus beiden ist und zwischen den Ereignissen unterscheiden muss.
Noderman

16
Dieser Thread ist eine gute Zusammenfassung, wie die Arbeit mit Knotenströmen aussieht.
Pomber


9

Code-Snippet zum Weiterleiten von Inhalten vom Web über http (s) zum Dateisystem. Wie @starbeamrainbowlabs bemerkte, macht das Ereignis finishArbeit

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

Das Ein-Ende funktioniert für mich und das Ende nicht. Danke dir!
Shaosh

1
In einem bestimmten Fall scheint das Ende zu feuern, bevor alle erwarteten Bytes eintreffen
Michael,

4

Ich habe in diesem Zusammenhang eine etwas andere Lösung für mein Problem gefunden. Gedanken, die es wert sind, geteilt zu werden.

Die meisten Beispiele werden readStreamsaus Dateien erstellt. Aber in meinem Fall readStreammuss aus einer JSONZeichenfolge erstellt werden, die aus einem Nachrichtenpool stammt.

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

Anstatt auf "Beenden" zu hören, haben Sie zwei Handler für "Schließen", vielleicht war das der Grund. Das "Finish" -Event funktioniert für mich.
Jowo

3

Hier ist eine Lösung, die Fehler in Anforderungen behandelt und einen Rückruf aufruft, nachdem die Datei geschrieben wurde:

request(opts)
    .on('error', function(err){ return callback(err)})
    .pipe(fs.createWriteStream(filename))
    .on('finish', function (err) {
        return callback(err);
    });
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.