diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 60286877928646..0ff6851df9bf27 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -59,9 +59,11 @@ function nop() {} const kFlush = Symbol('kFlush'); class WritableState extends WritableStateBase { - constructor(options, stream, isDuplex) { + constructor(options, stream) { super(options); + let isDuplex = options.isDuplex; + // Duplex streams are both readable and writable, but share // the same options object. // However, some cases require setting options to different @@ -207,6 +209,7 @@ function Writable(options) { WritableBase.call(this, { ...options, + isDuplex, start: function() { const state = this._writableState; if (!state.writing) { @@ -215,7 +218,8 @@ function Writable(options) { finishMaybe(this, state); }, write: writeOrBuffer, - flush: function(state, cb) { + flush: function(cb) { + const state = this._writableState; // .end() fully uncorks. if (state.corked) { state.corked = 1; @@ -226,7 +230,7 @@ function Writable(options) { finishMaybe(this, state); } - }, isDuplex, WritableState); + }, WritableState); } Writable.WritableState = WritableState; Writable.prototype = ObjectCreate(WritableBase.prototype); @@ -249,7 +253,9 @@ Writable.prototype.uncork = function() { // If we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(state, chunk, encoding, callback) { +function writeOrBuffer(chunk, encoding, callback) { + const state = this._writableState; + if (typeof callback !== 'function') callback = nop; diff --git a/lib/internal/streams/base.js b/lib/internal/streams/base.js index 9cde737c30b905..c020f2d223eac5 100644 --- a/lib/internal/streams/base.js +++ b/lib/internal/streams/base.js @@ -85,7 +85,7 @@ class WritableStateBase { const kWrite = Symbol('kWrite'); const kFlush = Symbol('kFlush'); -function WritableBase(options, isDuplex, State) { +function WritableBase(options, State = WritableStateBase) { if (typeof options.write !== 'function') { throw new ERR_INVALID_ARG_TYPE('option.write', 'function', options.write); } @@ -98,7 +98,7 @@ function WritableBase(options, isDuplex, State) { this[kWrite] = options.write; this[kFlush] = options.flush; - this._writableState = new State(options, this, isDuplex); + this._writableState = new State(options, this); destroyImpl.construct(this, options.start); } @@ -150,7 +150,7 @@ WritableBase.prototype.write = function(chunk, encoding, cb) { } // TODO(ronag): Move more logic from Writable into custom cb. - const ret = this[kWrite](state, chunk, encoding, cb); + const ret = this[kWrite](chunk, encoding, cb); // Return false if errored or destroyed in order to break // any synchronous while(stream.write(data)) loops. return ret && !state.errored && !state.destroyed; @@ -196,7 +196,7 @@ WritableBase.prototype.end = function(chunk, encoding, cb) { if (!state.errored && !state.ending) { state.ending = true; let called = false; - this[kFlush](state, (err) => { + this[kFlush]((err) => { if (called) { errorOrDestroy(this, new ERR_MULTIPLE_CALLBACK()); return;