wywołanie zwrotne do obsługi zakończenia potoku


196

Korzystam z następującego kodu node.js, aby pobrać dokumenty z jakiegoś adresu URL i zapisać go na dysku. Chcę otrzymywać informacje o pobraniu dokumentu. nie widziałem żadnego wywołania zwrotnego z potokiem. Lub, Czy jest jakieś zdarzenie „końcowe”, które można zarejestrować po zakończeniu pobierania?

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

Odpowiedzi:


302

Strumieniami są EventEmitters, dzięki czemu można słuchać niektórych wydarzeń. Jak powiedziałeś, istnieje finishzdarzenie na żądanie (wcześniej end).

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

Aby uzyskać więcej informacji o dostępnych zdarzeniach, sprawdź stronę dokumentacji strumienia .


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

6
dla mnie wydarzenie „zamknij”, a nie „koniec”r.on('close'), function () {...})
Judson,

9
Wydarzenie „koniec” jest teraz „zakończone”. Wydarzenia na rurze: nodejs.org/api/stream.html#stream_event_finish
Pier-Luc Gendreau

13
Zdarzenie „koniec” nadal istnieje i jest używane w strumieniach czytelnych. Strumienie do zapisu używają „wykończenia”. Wynika to z faktu, że strumień transformacji jest połączeniem obu i musi rozróżniać zdarzenia.
noderman

16
Ten wątek stanowi dobre podsumowanie tego, jak wygląda praca ze strumieniami węzłów.
pomber


9

Fragment kodu do przesyłania zawartości z sieci przez http (s) do systemu plików. Jak zauważyło @starbeamrainbowlabs, zdarzenie finishdziała

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

„Wykończenie” działa dla mnie, a „koniec” nie. Dziękuję Ci!
shaosh,

1
w jednym szczególnym przypadku zdaje się, że meta wystrzeliwuje, zanim dotrą wszystkie oczekiwane bajty
Michael

4

Znalazłem nieco inne rozwiązanie mojego problemu w tym kontekście. Myśl warta podzielenia się.

Większość przykładów tworzy się readStreamsz pliku. Ale w moim przypadku readStreammusi być utworzony z JSONciągu pochodzącego z puli komunikatów.

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

Zamiast nasłuchiwać „wykończenia” masz dwie procedury obsługi „zamknięcia”, być może to był powód. Wydarzenie „wykończenie” działa dla mnie.
jowo

3

Oto rozwiązanie, które obsługuje błędy w żądaniach i wywołuje wywołanie zwrotne po zapisaniu pliku:

request(opts)
    .on('error', function(err){ return callback(err)})
    .pipe(fs.createWriteStream(filename))
    .on('finish', function (err) {
        return callback(err);
    });
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.