stream: add readableEnded
Adds a readableEnded property and improved finished compat with possible stream-like objects. PR-URL: https://github.com/nodejs/node/pull/28814 Refs: https://github.com/nodejs/node/issues/28813 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
parent
0d7acfac82
commit
317fa3a757
@ -1129,6 +1129,15 @@ added: v12.7.0
|
|||||||
Getter for the property `encoding` of a given `Readable` stream. The `encoding`
|
Getter for the property `encoding` of a given `Readable` stream. The `encoding`
|
||||||
property can be set using the [`readable.setEncoding()`][] method.
|
property can be set using the [`readable.setEncoding()`][] method.
|
||||||
|
|
||||||
|
##### readable.readableEnded
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
* {boolean}
|
||||||
|
|
||||||
|
Becomes `true` when [`'end'`][] event is emitted.
|
||||||
|
|
||||||
##### readable.readableHighWaterMark
|
##### readable.readableHighWaterMark
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v9.3.0
|
added: v9.3.0
|
||||||
|
@ -205,6 +205,16 @@ Object.defineProperty(Readable.prototype, 'destroyed', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(Readable.prototype, 'readableEnded', {
|
||||||
|
// Making it explicit this property is not enumerable
|
||||||
|
// because otherwise some prototype manipulation in
|
||||||
|
// userland will fail
|
||||||
|
enumerable: false,
|
||||||
|
get() {
|
||||||
|
return this._readableState ? this._readableState.endEmitted : false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Readable.prototype.destroy = destroyImpl.destroy;
|
Readable.prototype.destroy = destroyImpl.destroy;
|
||||||
Readable.prototype._undestroy = destroyImpl.undestroy;
|
Readable.prototype._undestroy = destroyImpl.undestroy;
|
||||||
Readable.prototype._destroy = function(err, cb) {
|
Readable.prototype._destroy = function(err, cb) {
|
||||||
|
@ -132,7 +132,7 @@ const createReadableStreamAsyncIterator = (stream) => {
|
|||||||
[kLastReject]: { value: null, writable: true },
|
[kLastReject]: { value: null, writable: true },
|
||||||
[kError]: { value: null, writable: true },
|
[kError]: { value: null, writable: true },
|
||||||
[kEnded]: {
|
[kEnded]: {
|
||||||
value: stream._readableState.endEmitted,
|
value: stream.readableEnded || stream._readableState.endEmitted,
|
||||||
writable: true
|
writable: true
|
||||||
},
|
},
|
||||||
// The function passed to new Promise is cached so we avoid allocating a new
|
// The function passed to new Promise is cached so we avoid allocating a new
|
||||||
|
@ -42,7 +42,8 @@ function eos(stream, opts, callback) {
|
|||||||
if (!readable) callback.call(stream);
|
if (!readable) callback.call(stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
var readableEnded = stream._readableState && stream._readableState.endEmitted;
|
var readableEnded = stream.readableEnded ||
|
||||||
|
(stream._readableState && stream._readableState.endEmitted);
|
||||||
const onend = () => {
|
const onend = () => {
|
||||||
readable = false;
|
readable = false;
|
||||||
readableEnded = true;
|
readableEnded = true;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
const { Writable, Readable, Transform, finished } = require('stream');
|
const { Writable, Readable, Transform, finished } = require('stream');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
const EE = require('events');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { promisify } = require('util');
|
const { promisify } = require('util');
|
||||||
|
|
||||||
@ -175,3 +176,11 @@ const { promisify } = require('util');
|
|||||||
rs.push(null);
|
rs.push(null);
|
||||||
rs.resume();
|
rs.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const streamLike = new EE();
|
||||||
|
streamLike.readableEnded = true;
|
||||||
|
streamLike.readable = true;
|
||||||
|
finished(streamLike, common.mustCall);
|
||||||
|
streamLike.emit('close');
|
||||||
|
}
|
||||||
|
33
test/parallel/test-stream-readable-ended.js
Normal file
33
test/parallel/test-stream-readable-ended.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common');
|
||||||
|
const { Readable } = require('stream');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
// basic
|
||||||
|
{
|
||||||
|
// Find it on Readable.prototype
|
||||||
|
assert(Readable.prototype.hasOwnProperty('readableEnded'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// event
|
||||||
|
{
|
||||||
|
const readable = new Readable();
|
||||||
|
|
||||||
|
readable._read = () => {
|
||||||
|
// The state ended should start in false.
|
||||||
|
assert.strictEqual(readable.readableEnded, false);
|
||||||
|
readable.push('asd');
|
||||||
|
assert.strictEqual(readable.readableEnded, false);
|
||||||
|
readable.push(null);
|
||||||
|
assert.strictEqual(readable.readableEnded, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
readable.on('end', common.mustCall(() => {
|
||||||
|
assert.strictEqual(readable.readableEnded, true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
readable.on('data', common.mustCall(() => {
|
||||||
|
assert.strictEqual(readable.readableEnded, false);
|
||||||
|
}));
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user