2016-12-15 5 views
0

Мне любопытно, что мой поток PassThrough и почему он не закрывается после ресурса, я его закрываю. Я использую его как посредник, для одного ресурса требуется ReadableStream, и мне нужно передать пользователю WriteableStream, чтобы они могли писать базовый ресурс. Сначала Дуплексный поток казался идеальным, но требовал некоторой реализации, затем я нашел поток PassThrough.Node.js PassThrough поток не закрывается должным образом?

EDIT: Лучшее описание этой проблемы здесь: https://gist.github.com/four43/46fd38fd0c929b14deb6f1744b63026a

Оригинальный пример: Проверьте это:

const fs = require('fs'); 
const stream = require('stream'); 

const passThrough = new stream.PassThrough({allowHalfOpen: false}); 
const writeStream = new fs.createWriteStream('/tmp/output.txt'); 

passThrough.pipe(writeStream) 
    .on('end',() => console.log('full-end')) 
    .on('close',() => console.log('full-close')) 
    .on('unpipe',() => console.log('full-unpipe')) 
    .on('finish',() => console.log('full-finish')); 
passThrough 
    .on('end',() => console.log('passThrough-end')) 
    .on('close',() => console.log('passThrough-close')) 
    .on('unpipe',() => console.log('passThrough-unpipe')) 
    .on('finish',() => console.log('passThrough-finish')); 

passThrough.end('hello world'); 

Фактический выход:

passThrough-finish 
passThrough-end 
full-unpipe 
full-finish 
full-close 

Похоже на стороне записи это его работа, но «прочитанная» часть потока PassThrough не защищает закрытие e, даже несмотря на то, что опция allowHalfOpen была передана как ложная (и я могу проверить, какая опция была взята в отладчике).

Я все об этом не так? Как я буду распространять конец writeStream?

Спасибо.

Редактировать: Я обнаружил, что то же самое верно для трансформирующих потоков, они просто не закончены конусом, труба закрыта. Есть ли способ их вручную закрыть? transform.end() никогда не заставляет поток метать «закрытое» событие, просто «заканчивать» и «заканчивать» события, которые запускаются до того, как базовый ресурс завершится успешно.

Edit2: я соединял этот GIST: https://gist.github.com/four43/46fd38fd0c929b14deb6f1744b63026a

Это показывает мне, что читаемый в readable.pipe (запись) будет закрыта должным образом, когда записываемые заканчивается. Это заставило бы меня поверить, что когда я делаю transform.pipe (записываемый), он закрывает «читаемую» сторону потока преобразования, и поскольку я уже «закрыл» записываемую сторону с помощью .end(), он должен закрыть целое поток. Интересная заметка: чтение - это метание событий, хотя мы никогда не используем его в тесте 2. Может быть проблемой изоляции, но я думаю, что мой ожидания ожидания очень хорош.

ответ

0

Если вы хотите знать, когда writeStream сделано писать то просто слушать для 'finish' события на writeStream

const fs = require('fs'); 
const stream = require('stream'); 

const passThrough = new stream.PassThrough({allowHalfOpen: false}); 
const writeStream = new fs.createWriteStream('/tmp/output.txt'); 

passThrough 
    .on('error', (err) => console.error(err)) 
    .on('end',() => console.log('passThrough-end')) 
    .on('close',() => console.log('passThrough-close')) 
    .on('unpipe',() => console.log('passThrough-unpipe')) 
    .on('finish',() => console.log('passThrough-finish')); 

writeStream 
    .on('error', (err) => console.error(err)) 
    .on('close',() => console.log('full-close')) 
    .on('unpipe',() => console.log('full-unpipe')) 
    .on('finish',() => console.log('full-finish')); 

// passThrough-finish written because all Writes are complete 
passThrough.end('hello world'); 

passThrough.pipe(writeStream); 
+0

Я мог бы, но основной поток непрозрачен и скрыто от меня. (Я использую свой поток PassThrough и свяжу его с методом s3.upload() aws-sdk). Я отредактировал свой вопрос, чтобы показать непоследовательное поведение. – cr125rider

+0

@ cr125rider, почему вас это волнует, если писатель будет завершен? Если у вас нет доступа к нему, это не имеет значения, нет? В этом случае, зная, что ваш Readable закрыт, должно быть достаточно. Также стоит отметить, что для [Transform Streams] нет события '' close '' (https://nodejs.org/dist/latest-v7.x/docs/api/stream.html#stream_events_finish_and_end) – peteb

+0

Чтобы гарантировать содержимое базового потока завершено, вам нужно подождать, пока не будет выполнен поток записи. Если вы не будете осторожны, вы столкнетесь со всеми странными проблемами. Это на самом деле появилось из-за неудачного модульного теста, который искал что-то, что закончило писать в поток, прочитал файл, а не там. – cr125rider

Смежные вопросы