6

I have a stream that may or may not have already ended. If it has ended, I don't want to sit there forever waiting for the end event. How do I check?

cbnz
  • 656
  • 1
  • 9
  • 19

3 Answers3

4

If you absolutely have to, you can check stream._readableState.ended, at least in node 0.10 and 0.12. This isn't public API though so be careful. Also apparently all streams aren't guarantee to have this property too:

Worth reading on this:

https://github.com/hapijs/hapi/issues/2368

https://github.com/nodejs/node/issues/445

Matt Harrison
  • 13,381
  • 6
  • 48
  • 66
4

As of node 12.9.0, readable streams have a readableEnded property you can check – see readable.readableEnded in the Stream documentation.

(Writable streams have a corresponding property)

TehShrike
  • 9,855
  • 2
  • 33
  • 28
3

You probably shouldn't check, and instead attach an end event listener. When the stream ends you will get an end event.

If a [readable]stream is implemented correctly, you will get an end event when there is nothing left to read. For open-ended streams that don't end, you could implement an activity timer to see how long it's been since the stream was last readable, and decide after a certain amount of time to remove your listeners.

(function() {
    var timeout = null;
    var WAIT_TIME = 10 * 1000; // 10 Sec
    function stopListening( ) {
        stream.off('data', listener);
    }
    function listener( data ) {
        clearTimeout(timeout);
        timeout = setTimeout(stopListening, WAIT_TIME);
        // DO STUFF
    }
    timeout = setTimeout(stopListening, WAIT_TIME);
    stream.on('data', listener);
})();
TbWill4321
  • 8,626
  • 3
  • 27
  • 25
  • 3
    I don't have access to the stream until after the `end` event has fired – cbnz Aug 27 '15 at 22:36
  • 1
    You can pipe your input stream in a new stream.Readable, and attach your listeners to the wrapper. Then you don't have to worry about whether it has data or not, you just attach event handlers to handle both instances. – TbWill4321 Aug 27 '15 at 22:57