rappel pour gérer l'achèvement du tuyau


196

J'utilise le code node.js suivant pour télécharger des documents à partir d'une URL et l'enregistrer sur le disque. Je souhaite être informé du téléchargement du document. je n'ai vu aucun rappel avec pipe.Ou, y a-t-il un événement de fin qui peut être capturé à la fin du téléchargement?

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

Réponses:


302

Les flux sont EventEmitters pour que vous puissiez écouter certains événements. Comme vous l'avez dit, il y a un finishévénement à demander (précédemment end).

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

Pour plus d'informations sur les événements disponibles, vous pouvez consulter la page de documentation du flux .


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

6
pour moi, l'événement `` ferme '' plutôt que `` termine ''r.on('close'), function () {...})
— Judson

9
L'événement 'end' est maintenant 'finish' Événements Pipe: nodejs.org/api/stream.html#stream_event_finish
— Pier-Luc Gendreau

13
L'événement «end» existe toujours et est utilisé sur les flux lisibles. Les flux inscriptibles utilisent «finish». En effet, le flux de transformation est un mélange des deux et doit différencier les événements.
— noderman

16
Ce fil est un bon résumé de l'aspect du travail avec les flux de nœuds.
— bombardier

43

Basé sur le document nodejs, http://nodejs.org/api/stream.html#stream_event_finish , il devrait gérer l' finishévénement de writableStream .

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

La réponse acceptée ne fonctionne pas pour moi avec le nœud v0.12.7, mais votre solution le fait.
— Luca Steeb

9

Extrait de code pour diriger le contenu du Web via http (s) vers le système de fichiers. Comme l'a remarqué @starbeamrainbowlabs, l'événement finishfonctionne

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

La fonction «finition» fonctionne pour moi et «fin» ne fonctionne pas. Je vous remercie!
— shaosh

1
dans un cas particulier, l'arrivée semble se déclencher avant l'arrivée de tous les octets attendus
— Michael

4

J'ai trouvé une solution un peu différente de mon problème concernant ce contexte. Pensée à partager.

La plupart de l'exemple crée à readStreamspartir d'un fichier. Mais dans mon cas, readStreamdoit être créé à partir d'une JSONchaîne provenant d'un pool de messages.

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

Au lieu d'écouter «terminer», vous avez deux gestionnaires pour «fermer», c'était peut-être la raison. L'événement "finish" fonctionne pour moi.
— jowo

3

Voici une solution qui gère les erreurs dans les demandes et appelle un rappel après l'écriture du fichier:

request(opts)
    .on('error', function(err){ return callback(err)})
    .pipe(fs.createWriteStream(filename))
    .on('finish', function (err) {
        return callback(err);
    });
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.