@@ -8,12 +8,9 @@ const kLastPromise = Symbol('lastPromise');
8
8
const kHandlePromise = Symbol ( 'handlePromise' ) ;
9
9
const kStream = Symbol ( 'stream' ) ;
10
10
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
+ }
17
14
18
15
function readAndResolve ( iter ) {
19
16
const resolve = iter [ kLastResolve ] ;
@@ -26,7 +23,7 @@ function readAndResolve(iter) {
26
23
iter [ kLastPromise ] = null ;
27
24
iter [ kLastResolve ] = null ;
28
25
iter [ kLastReject ] = null ;
29
- resolve ( new AsyncIteratorRecord ( data , false ) ) ;
26
+ resolve ( createIterResult ( data , false ) ) ;
30
27
}
31
28
}
32
29
}
@@ -43,7 +40,7 @@ function onEnd(iter) {
43
40
iter [ kLastPromise ] = null ;
44
41
iter [ kLastResolve ] = null ;
45
42
iter [ kLastReject ] = null ;
46
- resolve ( new AsyncIteratorRecord ( null , true ) ) ;
43
+ resolve ( createIterResult ( null , true ) ) ;
47
44
}
48
45
iter [ kEnded ] = true ;
49
46
}
@@ -69,39 +66,13 @@ function wrapForNext(lastPromise, iter) {
69
66
} ;
70
67
}
71
68
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 ) ;
101
71
72
+ const ReadableStreamAsyncIteratorPrototype = Object . setPrototypeOf ( {
102
73
get stream ( ) {
103
74
return this [ kStream ] ;
104
- }
75
+ } ,
105
76
106
77
next ( ) {
107
78
// if we have detected an error in the meanwhile
@@ -112,7 +83,7 @@ const ReadableAsyncIterator = class ReadableAsyncIterator {
112
83
}
113
84
114
85
if ( this [ kEnded ] ) {
115
- return Promise . resolve ( new AsyncIteratorRecord ( null , true ) ) ;
86
+ return Promise . resolve ( createIterResult ( null , true ) ) ;
116
87
}
117
88
118
89
// if we have multiple next() calls
@@ -129,7 +100,7 @@ const ReadableAsyncIterator = class ReadableAsyncIterator {
129
100
// without triggering the next() queue
130
101
const data = this [ kStream ] . read ( ) ;
131
102
if ( data !== null ) {
132
- return Promise . resolve ( new AsyncIteratorRecord ( data , false ) ) ;
103
+ return Promise . resolve ( createIterResult ( data , false ) ) ;
133
104
}
134
105
135
106
promise = new Promise ( this [ kHandlePromise ] ) ;
@@ -138,7 +109,7 @@ const ReadableAsyncIterator = class ReadableAsyncIterator {
138
109
this [ kLastPromise ] = promise ;
139
110
140
111
return promise ;
141
- }
112
+ } ,
142
113
143
114
return ( ) {
144
115
// destroy(err, cb) is a private API
@@ -150,10 +121,45 @@ const ReadableAsyncIterator = class ReadableAsyncIterator {
150
121
reject ( err ) ;
151
122
return ;
152
123
}
153
- resolve ( new AsyncIteratorRecord ( null , true ) ) ;
124
+ resolve ( createIterResult ( null , true ) ) ;
154
125
} ) ;
155
126
} ) ;
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 ;
157
163
} ;
158
164
159
- module . exports = ReadableAsyncIterator ;
165
+ module . exports = createReadableStreamAsyncIterator ;
0 commit comments