обратный вызов для обработки завершения канала


196

Я использую следующий код node.js для загрузки документов с некоторого URL-адреса и сохранения его на диске. Я хочу получать информацию о том, когда документ будет загружен. Я не видел ни одного обратного вызова с pipe. Или, есть ли какое-нибудь событие end, которое может быть зафиксировано после завершения загрузки?

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

Ответы:


302

Потоки, EventEmitterтак что вы можете слушать определенные события. Как вы сказали, есть finishсобытие для запроса (ранее end).

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

Для получения дополнительной информации о том, какие события доступны, вы можете проверить страницу документации потока .


12
var r = request(...).on("end",function(){/* CALLBACK */}).pipe(...);
Денис Виталий

6
для меня событие «близко», а не «конец» работаетr.on('close'), function () {...})
Джадсон

9
Событие 'end' теперь стало событием 'finish' Pipe: nodejs.org/api/stream.html#stream_event_finish
Pier-Luc Gendreau

13
Событие 'end' все еще существует и используется в читаемых потоках. Доступные для записи потоки используют «конец». Это связано с тем, что поток Transform представляет собой сочетание обоих и должен различать события.
noderman

16
Этот поток - хорошее резюме того, как выглядит работа с потоками узлов.
Помбер

43

Основанный на документе nodejs http://nodejs.org/api/stream.html#stream_event_finish , он должен обрабатывать finishсобытие writableStream .

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

Принятый ответ не работает для меня с узлом v0.12.7, но ваше решение работает.
Лука Стиб

9

Фрагмент кода для передачи содержимого из Интернета через http (s) в файловую систему. Как заметил @starbeamrainbowlabs, событие finishработает

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

На «финише» у меня работает, а на «конце» нет. Спасибо!
Shaosh

1
в одном конкретном случае финиш, похоже, запускается до того, как прибывают все ожидаемые байты
Майкл

4

Я нашел немного другое решение моей проблемы в этом контексте. Мысль стоит поделиться.

Большая часть примера создается readStreamsиз файла. Но в моем случае readStreamэто должно быть создано из JSONстроки, поступающей из пула сообщений.

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

Вместо того, чтобы слушать «конец», у вас есть два обработчика «закрыть», возможно, в этом была причина. Событие "финиш" работает на меня.
Jowo

3

Вот решение, которое обрабатывает ошибки в запросах и вызывает обратный вызов после записи файла:

request(opts)
    .on('error', function(err){ return callback(err)})
    .pipe(fs.createWriteStream(filename))
    .on('finish', function (err) {
        return callback(err);
    });
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.