From d878de69243a3d8284d6239b82de4ed68f02851f Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 3 Feb 2015 19:01:56 -0500 Subject: [PATCH] Ready promise caching --- .../lib/exclusive-stream-reader.js | 1 + .../lib/readable-stream-abstract-ops.js | 4 ++++ reference-implementation/lib/readable-stream.js | 15 ++++++++++----- .../test/readable-stream.js | 17 +++++++++++++++++ 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/reference-implementation/lib/exclusive-stream-reader.js b/reference-implementation/lib/exclusive-stream-reader.js index 0e5a3a7da..a96586b3c 100644 --- a/reference-implementation/lib/exclusive-stream-reader.js +++ b/reference-implementation/lib/exclusive-stream-reader.js @@ -12,6 +12,7 @@ export default class ExclusiveStreamReader { } stream._readableStreamReader = this; + stream._readyPromiseCache = undefined; this._encapsulatedReadableStream = stream; diff --git a/reference-implementation/lib/readable-stream-abstract-ops.js b/reference-implementation/lib/readable-stream-abstract-ops.js index f40010697..c8e35a862 100644 --- a/reference-implementation/lib/readable-stream-abstract-ops.js +++ b/reference-implementation/lib/readable-stream-abstract-ops.js @@ -39,6 +39,7 @@ export function CallReadableStreamPull(stream) { export function CloseReadableStream(stream) { stream._state = 'closed'; + stream._readyPromiseCache = undefined; stream._resolveClosedPromise(undefined); if (stream._readableStreamReader !== undefined) { @@ -106,6 +107,7 @@ export function CreateReadableStreamEnqueueFunction(stream) { if (stream._state === 'waiting') { stream._state = 'readable'; + stream._readyPromiseCache = undefined; stream._resolveReadyPromise(undefined); } @@ -126,6 +128,7 @@ export function CreateReadableStreamErrorFunction(stream) { } if (stream._state === 'waiting' || stream._state === 'readable') { stream._state = 'errored'; + stream._readyPromiseCache = undefined; stream._storedError = e; stream._rejectClosedPromise(e); if (stream._readableStreamReader !== undefined) { @@ -180,6 +183,7 @@ export function ReadFromReadableStream(stream) { CloseReadableStream(stream); } else { stream._state = 'waiting'; + stream._readyPromiseCache = undefined; stream._initReadyPromise(); } } diff --git a/reference-implementation/lib/readable-stream.js b/reference-implementation/lib/readable-stream.js index 0e2f85943..8526f6474 100644 --- a/reference-implementation/lib/readable-stream.js +++ b/reference-implementation/lib/readable-stream.js @@ -15,6 +15,7 @@ export default class ReadableStream { this._draining = false; this._pulling = false; this._readableStreamReader = undefined; + this._readyPromiseCache = undefined; this._enqueue = CreateReadableStreamEnqueueFunction(this); this._close = CreateReadableStreamCloseFunction(this); @@ -190,15 +191,19 @@ export default class ReadableStream { return Promise.reject(new TypeError('ReadableStream.prototype.ready can only be used on a ReadableStream')); } - if (this._readableStreamReader !== undefined) { - return this._readableStreamReader._lockReleased.then(() => this.ready); + if (this._readyPromiseCache !== undefined) { + return this._readyPromiseCache; } - if (this._state === 'waiting') { - return this._readyPromise.then(() => this.ready); + if (this._readableStreamReader !== undefined) { + this._readyPromiseCache = this._readableStreamReader._lockReleased.then(() => this.ready); + } else if (this._state === 'waiting') { + this._readyPromiseCache = this._readyPromise.then(() => this.ready); + } else { + this._readyPromiseCache = this._readyPromise; } - return this._readyPromise; + return this._readyPromiseCache; } _initReadyPromise() { diff --git a/reference-implementation/test/readable-stream.js b/reference-implementation/test/readable-stream.js index 181c822be..aed87a678 100644 --- a/reference-implementation/test/readable-stream.js +++ b/reference-implementation/test/readable-stream.js @@ -680,3 +680,20 @@ test('ReadableStream should call underlying source methods as methods', t => { rs.ready.then(() => rs.cancel()); }); + +test('ReadableStream ready returns the same value when called on a new, empty stream', t => { + var rs = new ReadableStream(); + t.equal(rs.ready, rs.ready, 'rs.ready should not change between gets'); + t.end(); +}); + +test('ReadableStream ready returns the same value when called on a readable stream', t => { + var rs = new ReadableStream({ + start(enqueue) { + enqueue('a'); + } + }); + + t.equal(rs.ready, rs.ready, 'rs.ready should not change between gets'); + t.end(); +});