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


196

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

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

Відповіді:


302

Потоки є EventEmitters, щоб ви могли слухати певні події. Як ви сказали, є finishподія для запиту (раніше end).

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

Для отримання додаткової інформації про те, які події доступні, ви можете переглянути сторінку документації на потоки .


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

6
для мене подія «закривається», а не «закінчується»r.on('close'), function () {...})
— Джудсон

9
"Закінчення" події зараз закінчується " Трубові
— Pier-Luc Gendreau

13
Подія 'end' все ще існує і використовується в читаних потоках. Записувані потоки використовують "закінчення". Це тому, що потік «Трансформація» - це поєднання обох і потребує розмежування подій.
— нодерман

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

"Оздоблення" працює для мене, а "кінець" - ні. Дякую!
— шаош

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.