2012-07-12 7 views
143

Ich verwende den folgenden node.js-Code, um Dokumente von einer URL herunterzuladen und auf der Festplatte zu speichern. Ich möchte informiert werden, wenn das Dokument heruntergeladen wird. Ich habe noch keinen Callback mit pipe gesehen. Oder, gibt es irgendein 'Ende'-Ereignis, das nach Abschluss des Downloads erfasst werden kann?Rückruf zur Bearbeitung der Pipeline

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

Antwort

218

Streams sind EventEmitter s, damit Sie bestimmte Ereignisse hören können. Wie Sie sagten, gibt es ein finish Ereignis für die Anfrage (zuvor end).

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

Weitere Informationen darüber, welche Ereignisse verfügbar sind, finden Sie unter .

+11

'var r = Anfrage (...) auf ("end", Funktion () {/ * CALLBACK * /}). Pipe (...); ' –

+6

für mich ist das Event 'close', statt 'end'' r.on ('close'), function() {... }) ' – Judson

+8

Das Ereignis 'end' ist jetzt 'finish' Pipe-Ereignisse: http://nodejs.org/api/stream.html#stream_event_finish –

28

Basierend auf dem nodejs Dokument, http://nodejs.org/api/stream.html#stream_event_finish, sollte es das Ereignis finish von writableStream verarbeiten.

var writable = getWriteable(); 
var readable = getReadable(); 
readable.pipe(writable); 
writable.on('finish', function(){ ... }); 
+0

Die akzeptierte Antwort funktioniert nicht mit Knoten v0.12.7, aber Ihre Lösung funktioniert. –

6

Code-Snippet für die Übertragung von Inhalten vom Web über http (s) zum Dateisystem. Als @starbeamrainbowlabs Ereignis bemerkt finish tut Job

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

Das 'Ende' funktioniert für mich und 'Ende' nicht. Vielen Dank! – shaosh

+0

in einem bestimmten Fall scheint Finish zu feuern, bevor alle erwarteten Bytes ankommen – Michael

1

ich eine etwas andere Lösung meines Problems zu diesem Zusammenhang gefunden. Gedanken wert, geteilt zu werden.

Die meisten der Beispiel erstellen readStreams aus Datei. Aber in meinem Fall muss readStream von JSON String aus einem Nachrichtenpool erstellt werden.

var jsonStream = through2.obj(function(chunk, encoding, callback) { 
        this.push(JSON.stringify(chunk, null, 4) + '\n'); 
        callback(); 
       }); 
// message.vale --> valeu/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); 
+0

Anstatt auf "Finish" zu warten, haben Sie zwei Handler für "close", vielleicht war das der Grund. Das "Finish" Event funktioniert für mich. – jowo

0

Hier ist eine Lösung, die einen Rückruf Fehler in Anfragen und Anrufe behandelt, nachdem die Datei geschrieben wird.

request(opts) 
    .on('error', function(err){ return callback(err)}) 
    .pipe(fs.createWriteStream(filename)) 
    .on('finish', function (err) { 
     return callback(err); 
    }); 
Verwandte Themen