Skip to content

Commit 7c5e322

Browse files
rluvatonruyadorno
authored andcommitted
stream: improve webstream readable async iterator performance
PR-URL: #49662 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
1 parent f611583 commit 7c5e322

1 file changed

Lines changed: 44 additions & 29 deletions

File tree

‎lib/internal/webstreams/readablestream.js‎

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,13 @@ class ReadableStream {
479479

480480
// eslint-disable-next-line no-use-before-define
481481
constreader=newReadableStreamDefaultReader(this);
482-
letdone=false;
482+
483+
// No __proto__ here to avoid the performance hit.
484+
conststate={
485+
done: false,
486+
current: undefined,
487+
};
483488
letstarted=false;
484-
letcurrent;
485489

486490
// The nextSteps function is not an async function in order
487491
// to make it more efficient. Because nextSteps explicitly
@@ -490,7 +494,7 @@ class ReadableStream {
490494
// unnecessary Promise allocations to occur, which just add
491495
// cost.
492496
functionnextSteps(){
493-
if(done)
497+
if(state.done)
494498
returnPromiseResolve({done: true,value: undefined});
495499

496500
if(reader[kState].stream===undefined){
@@ -500,31 +504,15 @@ class ReadableStream {
500504
}
501505
constpromise=createDeferredPromise();
502506

503-
readableStreamDefaultReaderRead(reader,{
504-
[kChunk](chunk){
505-
current=undefined;
506-
promise.resolve({value: chunk,done: false});
507-
},
508-
[kClose](){
509-
current=undefined;
510-
done=true;
511-
readableStreamReaderGenericRelease(reader);
512-
promise.resolve({done: true,value: undefined});
513-
},
514-
[kError](error){
515-
current=undefined;
516-
done=true;
517-
readableStreamReaderGenericRelease(reader);
518-
promise.reject(error);
519-
},
520-
});
507+
// eslint-disable-next-line no-use-before-define
508+
readableStreamDefaultReaderRead(reader,newReadableStreamAsyncIteratorReadRequest(reader,state,promise));
521509
returnpromise.promise;
522510
}
523511

524512
asyncfunctionreturnSteps(value){
525-
if(done)
513+
if(state.done)
526514
return{done: true, value };// eslint-disable-line node-core/avoid-prototype-pollution
527-
done=true;
515+
state.done=true;
528516

529517
if(reader[kState].stream===undefined){
530518
thrownewERR_INVALID_STATE.TypeError(
@@ -561,19 +549,19 @@ class ReadableStream {
561549
// need to investigate if it's a bug in our impl or
562550
// the spec.
563551
if(!started){
564-
current=PromiseResolve();
552+
state.current=PromiseResolve();
565553
started=true;
566554
}
567-
current=current!==undefined ?
568-
PromisePrototypeThen(current,nextSteps,nextSteps) :
555+
state.current=state.current!==undefined ?
556+
PromisePrototypeThen(state.current,nextSteps,nextSteps) :
569557
nextSteps();
570-
returncurrent;
558+
returnstate.current;
571559
},
572560

573561
return(error){
574-
returncurrent ?
562+
returnstate.current ?
575563
PromisePrototypeThen(
576-
current,
564+
state.current,
577565
()=>returnSteps(error),
578566
()=>returnSteps(error)) :
579567
returnSteps(error);
@@ -774,6 +762,33 @@ function createReadableStreamBYOBRequest(controller, view) {
774762
returnstream;
775763
}
776764

765+
classReadableStreamAsyncIteratorReadRequest{
766+
constructor(reader,state,promise){
767+
this.reader=reader;
768+
this.state=state;
769+
this.promise=promise;
770+
}
771+
772+
[kChunk](chunk){
773+
this.state.current=undefined;
774+
this.promise.resolve({value: chunk,done: false});
775+
}
776+
777+
[kClose](){
778+
this.state.current=undefined;
779+
this.state.done=true;
780+
readableStreamReaderGenericRelease(this.reader);
781+
this.promise.resolve({done: true,value: undefined});
782+
}
783+
784+
[kError](error){
785+
this.state.current=undefined;
786+
this.state.done=true;
787+
readableStreamReaderGenericRelease(this.reader);
788+
this.promise.reject(error);
789+
}
790+
}
791+
777792
classDefaultReadRequest{
778793
constructor(){
779794
this[kState]=createDeferredPromise();

0 commit comments

Comments
 (0)