Alicia
Alicia

Reputation: 1161

How to handle end signal in a node.js Writable stream?

Using the stream.Writable base class of node.js 0.10, how can I handle the case of a consumer calling .end() and thus signaling no more data will be available?

In the documentation the only method told to be implemented in Writable subclasses is _write, but I can't find any clean way to notice when the input has been exhausted.

Upvotes: 5

Views: 3915

Answers (5)

Antoine
Antoine

Reputation: 14094

I know this is old, but I ran into this in 2020. If others find their way here: this is now implemented in Writable._final() as documented here

Upvotes: 3

Loic
Loic

Reputation: 184

from the source code of nodejs writable streams. calling end will fire finish event if the streams is able to be ended. If you the streams doesn't have a _final function, it will be a prefinish event fired also.

Upvotes: 0

700 Software
700 Software

Reputation: 87873

The answer I found was to listen to the finish event.

When the end() method has been called, and all data has been flushed to the underlying system, this event is emitted.

I haven't tested it yet, but the way I'm reading this, all calls to _write must be completed before the finish event is emitted.

Upvotes: 3

Alicia
Alicia

Reputation: 1161

Embarrassingly, as of 0.10, node's stream.Writable does not support this in a standard, clean way. This issue is already being discussed here: https://github.com/joyent/node/issues/7348

In that page several workarounds are proposed. TomFrost's flushwritable module looks like an acceptable solution for the time being.

That module provides a FlushWritable class which is used exactly like stream.Writable but supporting a new _flush method which is invoked after the consumer calls .end() but before the finish event is emitted.

Upvotes: 0

Rodrigo Medeiros
Rodrigo Medeiros

Reputation: 7862

Considering what you asked

how can I handle the case of a consumer calling .end() and thus signaling no more data will be available?

, you should check when your input (a readable stream) has ended, not your output (your writable stream). So, in this case, you can check for the end event on your readable stream, like:

readableStream.on('end', function () {
  // do what you want with your writable stream, maybe call the end() method
  writableStream.end();
});

You can even pipe the readable stream to the writable stream, if you don't want to manage the flow yourself:

readableStream.pipe(writableStream);

Upvotes: -1

Related Questions