diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 8db4f55a0..62e070576 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -304,6 +304,10 @@ Writable.prototype._write = function(chunk, cb) { Writable.prototype.end = function(chunk, encoding, cb) { var state = this._writableState; + // ignore unnecessary end() calls. + if (state.ending || state.ended || state.finished) + return; + if (typeof chunk === 'function') { cb = chunk; chunk = null; @@ -313,28 +317,17 @@ Writable.prototype.end = function(chunk, encoding, cb) { encoding = null; } - if (chunk) - this.write(chunk, encoding); - - // ignore unnecessary end() calls. - if (!state.ending && !state.ended && !state.finished) - endWritable(this, state, !!chunk, cb); -}; - -function endWritable(stream, state, hadChunk, cb) { state.ending = true; - if (!hadChunk && - state.length === 0 && - !state.finishing) { + if (chunk) + this.write(chunk, encoding, cb); + else if (state.length === 0 && !state.finishing && !state.finished) { state.finishing = true; - stream.emit('finish'); + this.emit('finish'); state.finished = true; + if (cb) process.nextTick(cb); + } else if (cb) { + this.once('finish', cb); } - if (cb) { - if (state.finished || state.finishing) - process.nextTick(cb); - else - stream.once('finish', cb); - } + state.ended = true; }; diff --git a/test/simple/test-stream2-writable.js b/test/simple/test-stream2-writable.js index 537660263..efd49021b 100644 --- a/test/simple/test-stream2-writable.js +++ b/test/simple/test-stream2-writable.js @@ -311,19 +311,3 @@ test('duplexes are pipable', function(t) { assert(!gotError); t.end(); }); - -test('end(chunk) two times is an error', function(t) { - var w = new W(); - w._write = function() {}; - var gotError = false; - w.on('error', function(er) { - gotError = true; - t.equal(er.message, 'write after end'); - }); - w.end('this is the end'); - w.end('and so is this'); - process.nextTick(function() { - assert(gotError); - t.end(); - }); -});