@@ -8,12 +8,9 @@ const kLastPromise = Symbol('lastPromise');
88const kHandlePromise = Symbol ( 'handlePromise' ) ;
99const kStream = Symbol ( 'stream' ) ;
1010
11- const AsyncIteratorRecord = class AsyncIteratorRecord {
12- constructor ( value , done ) {
13- this . done = done ;
14- this . value = value ;
15- }
16- } ;
11+ function createIterResult ( value , done ) {
12+ return { value, done } ;
13+ }
1714
1815function readAndResolve ( iter ) {
1916 const resolve = iter [ kLastResolve ] ;
@@ -26,7 +23,7 @@ function readAndResolve(iter) {
2623 iter [ kLastPromise ] = null ;
2724 iter [ kLastResolve ] = null ;
2825 iter [ kLastReject ] = null ;
29- resolve ( new AsyncIteratorRecord ( data , false ) ) ;
26+ resolve ( createIterResult ( data , false ) ) ;
3027 }
3128 }
3229}
@@ -43,7 +40,7 @@ function onEnd(iter) {
4340 iter [ kLastPromise ] = null ;
4441 iter [ kLastResolve ] = null ;
4542 iter [ kLastReject ] = null ;
46- resolve ( new AsyncIteratorRecord ( null , true ) ) ;
43+ resolve ( createIterResult ( null , true ) ) ;
4744 }
4845 iter [ kEnded ] = true ;
4946}
@@ -69,39 +66,13 @@ function wrapForNext(lastPromise, iter) {
6966 } ;
7067}
7168
72- const ReadableAsyncIterator = class ReadableAsyncIterator {
73- constructor ( stream ) {
74- this [ kStream ] = stream ;
75- this [ kLastResolve ] = null ;
76- this [ kLastReject ] = null ;
77- this [ kError ] = null ;
78- this [ kEnded ] = false ;
79- this [ kLastPromise ] = null ;
80-
81- stream . on ( 'readable' , onReadable . bind ( null , this ) ) ;
82- stream . on ( 'end' , onEnd . bind ( null , this ) ) ;
83- stream . on ( 'error' , onError . bind ( null , this ) ) ;
84-
85- // the function passed to new Promise
86- // is cached so we avoid allocating a new
87- // closure at every run
88- this [ kHandlePromise ] = ( resolve , reject ) => {
89- const data = this [ kStream ] . read ( ) ;
90- if ( data ) {
91- this [ kLastPromise ] = null ;
92- this [ kLastResolve ] = null ;
93- this [ kLastReject ] = null ;
94- resolve ( new AsyncIteratorRecord ( data , false ) ) ;
95- } else {
96- this [ kLastResolve ] = resolve ;
97- this [ kLastReject ] = reject ;
98- }
99- } ;
100- }
69+ const AsyncIteratorPrototype = Object . getPrototypeOf (
70+ Object . getPrototypeOf ( async function * ( ) { } ) . prototype ) ;
10171
72+ const ReadableStreamAsyncIteratorPrototype = Object . setPrototypeOf ( {
10273 get stream ( ) {
10374 return this [ kStream ] ;
104- }
75+ } ,
10576
10677 next ( ) {
10778 // if we have detected an error in the meanwhile
@@ -112,7 +83,7 @@ const ReadableAsyncIterator = class ReadableAsyncIterator {
11283 }
11384
11485 if ( this [ kEnded ] ) {
115- return Promise . resolve ( new AsyncIteratorRecord ( null , true ) ) ;
86+ return Promise . resolve ( createIterResult ( null , true ) ) ;
11687 }
11788
11889 // if we have multiple next() calls
@@ -129,7 +100,7 @@ const ReadableAsyncIterator = class ReadableAsyncIterator {
129100 // without triggering the next() queue
130101 const data = this [ kStream ] . read ( ) ;
131102 if ( data !== null ) {
132- return Promise . resolve ( new AsyncIteratorRecord ( data , false ) ) ;
103+ return Promise . resolve ( createIterResult ( data , false ) ) ;
133104 }
134105
135106 promise = new Promise ( this [ kHandlePromise ] ) ;
@@ -138,7 +109,7 @@ const ReadableAsyncIterator = class ReadableAsyncIterator {
138109 this [ kLastPromise ] = promise ;
139110
140111 return promise ;
141- }
112+ } ,
142113
143114 return ( ) {
144115 // destroy(err, cb) is a private API
@@ -150,10 +121,45 @@ const ReadableAsyncIterator = class ReadableAsyncIterator {
150121 reject ( err ) ;
151122 return ;
152123 }
153- resolve ( new AsyncIteratorRecord ( null , true ) ) ;
124+ resolve ( createIterResult ( null , true ) ) ;
154125 } ) ;
155126 } ) ;
156- }
127+ } ,
128+ } , AsyncIteratorPrototype ) ;
129+
130+ const createReadableStreamAsyncIterator = ( stream ) => {
131+ const iterator = Object . create ( ReadableStreamAsyncIteratorPrototype , {
132+ [ kStream ] : { value : stream , writable : true } ,
133+ [ kLastResolve ] : { value : null , writable : true } ,
134+ [ kLastReject ] : { value : null , writable : true } ,
135+ [ kError ] : { value : null , writable : true } ,
136+ [ kEnded ] : { value : false , writable : true } ,
137+ [ kLastPromise ] : { value : null , writable : true } ,
138+ // the function passed to new Promise
139+ // is cached so we avoid allocating a new
140+ // closure at every run
141+ [ kHandlePromise ] : {
142+ value : ( resolve , reject ) => {
143+ const data = iterator [ kStream ] . read ( ) ;
144+ if ( data ) {
145+ iterator [ kLastPromise ] = null ;
146+ iterator [ kLastResolve ] = null ;
147+ iterator [ kLastReject ] = null ;
148+ resolve ( createIterResult ( data , false ) ) ;
149+ } else {
150+ iterator [ kLastResolve ] = resolve ;
151+ iterator [ kLastReject ] = reject ;
152+ }
153+ } ,
154+ writable : true ,
155+ } ,
156+ } ) ;
157+
158+ stream . on ( 'readable' , onReadable . bind ( null , iterator ) ) ;
159+ stream . on ( 'end' , onEnd . bind ( null , iterator ) ) ;
160+ stream . on ( 'error' , onError . bind ( null , iterator ) ) ;
161+
162+ return iterator ;
157163} ;
158164
159- module . exports = ReadableAsyncIterator ;
165+ module . exports = createReadableStreamAsyncIterator ;
0 commit comments