retorno de chamada para lidar com a conclusão do pipe


196

Estou usando o seguinte código node.js para baixar documentos de algum URL e salvá-lo no disco. Quero ser informado sobre quando o documento é baixado. Eu não vi nenhum retorno de chamada com o pipe.Or, Existe algum evento 'final' que pode ser capturado após a conclusão do download?

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

Respostas:


302

Os fluxos são EventEmitters para que você possa ouvir determinados eventos. Como você disse, há um finishevento para solicitação (anteriormente end).

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

Para obter mais informações sobre quais eventos estão disponíveis, consulte a página de documentação do fluxo .


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

6
para mim o evento 'fechar', em vez de 'final', funcionar.on('close'), function () {...})
Judson

9
O evento 'fim' é agora 'Concluir' eventos de tubos: nodejs.org/api/stream.html#stream_event_finish
Pier-Luc Gendreau

13
O evento 'end' ainda existe e é usado em fluxos legíveis. Fluxos graváveis ​​usam 'finish'. Isso ocorre porque o fluxo Transform é uma mistura de ambos e precisa diferenciar os eventos.
Nodeman

16
Este encadeamento é um bom resumo de como é o trabalho com fluxos de nós.
pomber


9

Fragmento de código para canalizar o conteúdo da Web via http (s) para o sistema de arquivos. Como @starbeamrainbowlabs notou que o 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);
});

O on 'finish' funciona para mim e o 'end' não. Obrigado!
shaosh 20/09/2015

1
em um caso particular, acabamento parece estar disparando antes de todos os bytes esperados chegam
Michael

4

Encontrei uma solução um pouco diferente do meu problema em relação a esse contexto. Vale a pena compartilhar.

A maioria do exemplo é criada a readStreamspartir do arquivo Mas, no meu caso readStream, deve ser criado a partir JSONde uma string proveniente de um pool de mensagens.

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

Em vez de ouvir "concluir", você tem dois manipuladores para "fechar", talvez seja esse o motivo. O evento "finish" funciona para mim.
Jowo

3

Aqui está uma solução que lida com erros nas solicitações e chama um retorno de chamada após a gravação do arquivo:

request(opts)
    .on('error', function(err){ return callback(err)})
    .pipe(fs.createWriteStream(filename))
    .on('finish', function (err) {
        return callback(err);
    });
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.