2015-10-17 2 views
3

Стандартная рекомендация по определению того, нужно ли ждать события drain на process.stdout, является проверка того, возвращает ли он false при записи на него.Узел трубы к стандарту stdout - как я могу сказать, если он слит?

Как я могу проверить, подключил ли я к нему другой поток? Казалось бы, этот поток может испускать finish, прежде чем весь вывод будет фактически записан. Могу ли я сделать что-то вроде этого?

upstreamOfStdout.on('finish', function(){ 
    if(!process.stdout.write('')) { 
    process.stdout.on('drain', function() { done("I'm done"); }); 
    } 
    else { 
    done("I'm done"); 
    } 
}); 
upstreamOfStdout.pipe(process.stdout); 

Я предпочитаю ответ, который не зависит от внутренних элементов любых потоков. Просто учитывая, что потоки соответствуют интерфейсу потока узлов, каков канонический способ сделать это?

EDIT:

Больший контекст является оберткой:

new Promise(function(resolve, reject){ 
    stream.on(<some-event>, resolve); 
    ... (perhaps something else here?) 
}); 

где stream может быть process.stdout или что-то другое, что имеет другой через поток поступает в него.

Моя программа выходит, когда вызывается resolve. Я предполагаю, что код Promise поддерживает программу до тех пор, пока все обещания не будут решены.

Я столкнулся с этой ситуацией несколько раз и всегда использовал хаки для решения проблемы (например, есть несколько частных членов в process.stdout, которые являются полезными.) Но я действительно хотел бы решить это раз и навсегда (или узнать что это ошибка, поэтому я могу отследить проблему и исправить свои хаки, когда она разрешится, по крайней мере): как мне сказать, когда поток вниз по течению от другого закончен, обрабатывая его вход?

ответ

2

Прежде всего, насколько я могу видеть из documentation, этот поток никогда не испускает событие finish, так что вряд ли вы сможете положиться на это.

Кроме того, из документации выше упоминалось, drain событие, кажется, используется для уведомления пользователя о том, когда stream готов принять больше данных после того, как метод .write вернулся false. В любом случае вы можете сделать вывод, что это означает, что все остальные данные были написаны. Из документации для метода write действительно мы выводим, что значение false (ака, пожалуйста, прекратите нажимать данные) не является обязательным, и вы можете свободно игнорировать его, но последующие данные, вероятно, будут заполнены в памяти, позволяя использовать его для роста.

Из-за этого, основываясь на моем предположении на единственной документации, я полагаю, вы можете положиться на событие drain, чтобы знать, когда все данные были хорошо обработаны или могут быть вымыты.

Это также говорит о том, что нет четкого способа узнать, когда все данные были отправлены на консоль.

Наконец, вы можете прослушивать событие stream, связанное с сообщением о том, когда оно полностью поглощено, независимо от того, было ли оно записано на консоль или данные по-прежнему буферизуются в потоке консоли. Конечно, вы также можете свободно игнорировать проблему, потому что полностью потребленный поток должен быть хорошо обработан node.js, таким образом, отброшен, и вам больше не придется иметь дело с ним, когда вы передадите его во второй поток.

+0

Проблема, с которой я сталкиваюсь, заключается в том, что, не слушая утечки, программа завершается прежде, чем все будет записано, но если я слушаю утечку, это иногда никогда не происходит. Я полагаю, что утечка испускается только тогда, когда данные буферизуются, но я не знаю, буферизованы ли данные или нет. Кажется, что они не документированы, чтобы спросить, закончил ли поток запись или нет. – shaunc

+0

Буферизация происходит, когда метод 'write' возвращает' false', или, по крайней мере, это то, что указано в документации. Таким образом, событие «стока» происходит после такого случая. Имейте в виду, что ваша программа останется в живых, если у вас есть что-то значимое в цикле, который будет выполнен. Вы пытались прослушивать первый поток для события «end», а не последнего? – skypjack

+0

Я считаю, что 'end' устарел для записываемых потоков -' finish' - это событие для прослушивания. Как вы можете видеть из моего примера кода, я слушаю, как закончить. Вы правы в том, что «буферизация происходит, когда метод write возвращает false» - текущий вопрос заключается в том, что делать, если вы не можете увидеть возврат 'write', потому что вы использовали канал для отправки данных. Например, записывает пустую строку после получения «финиша» от официально утвержденного восходящего потока? Я был бы очень признателен за ответ от сопровождающего или ссылку на то, что они написали, поскольку документ кажется неубедительным. – shaunc

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