@@ -40,9 +40,8 @@ class Dir {
4040  #options; 
4141  #readPromisified; 
4242  #closePromisified; 
43-   // Either `null` or an Array of pending operations (= functions to be called 
44-   // once the current operation is done). 
4543  #operationQueue =  null ; 
44+   #handlerQueue =  [ ] ; 
4645
4746  constructor ( handle ,  path ,  options )  { 
4847    if  ( handle  ==  null )  throw  new  ERR_MISSING_ARGS ( 'handle' ) ; 
@@ -67,6 +66,33 @@ class Dir {
6766    return  this . #path; 
6867  } 
6968
69+   #processHandlerQueue( )  { 
70+     while  ( this . #handlerQueue. length  >  0 )  { 
71+       const  handler  =  ArrayPrototypeShift ( this . #handlerQueue) ; 
72+       const  {  handle,  path }  =  handler ; 
73+ 
74+       const  result  =  handle . read ( 
75+         this . #options. encoding , 
76+         this . #options. bufferSize , 
77+       ) ; 
78+ 
79+       if  ( result  !==  null )  { 
80+         this . processReadResult ( path ,  result ) ; 
81+         if  ( result . length  >  0 )  { 
82+           ArrayPrototypePush ( this . #handlerQueue,  handler ) ; 
83+         } 
84+       }  else  { 
85+         handle . close ( ) ; 
86+       } 
87+ 
88+       if  ( this . #bufferedEntries. length  >  0 )  { 
89+         break ; 
90+       } 
91+     } 
92+ 
93+     return  this . #bufferedEntries. length  >  0 ; 
94+   } 
95+ 
7096  read ( callback )  { 
7197    return  this . #readImpl( true ,  callback ) ; 
7298  } 
@@ -89,7 +115,7 @@ class Dir {
89115      return ; 
90116    } 
91117
92-     if  ( this . #bufferedEntries . length   >   0 )  { 
118+     if  ( this . #processHandlerQueue ( ) )  { 
93119      try  { 
94120        const  dirent  =  ArrayPrototypeShift ( this . #bufferedEntries) ; 
95121
@@ -159,25 +185,11 @@ class Dir {
159185      this . #options. encoding , 
160186    ) ; 
161187
162-     // Terminate early, since it's already thrown. 
163188    if  ( handle  ===  undefined )  { 
164189      return ; 
165190    } 
166191
167-     // Fully read the directory and buffer the entries. 
168-     // This is a naive solution and for very large sub-directories 
169-     // it can even block the event loop. Essentially, `bufferSize` is 
170-     // not respected for recursive mode. This is a known limitation. 
171-     // Issue to fix: https://github.com/nodejs/node/issues/55764 
172-     let  result ; 
173-     while  ( ( result  =  handle . read ( 
174-       this . #options. encoding , 
175-       this . #options. bufferSize , 
176-     ) ) )  { 
177-       this . processReadResult ( path ,  result ) ; 
178-     } 
179- 
180-     handle . close ( ) ; 
192+     ArrayPrototypePush ( this . #handlerQueue,  {  handle,  path } ) ; 
181193  } 
182194
183195  readSync ( )  { 
@@ -189,7 +201,7 @@ class Dir {
189201      throw  new  ERR_DIR_CONCURRENT_OPERATION ( ) ; 
190202    } 
191203
192-     if  ( this . #bufferedEntries . length   >   0 )  { 
204+     if  ( this . #processHandlerQueue ( ) )  { 
193205      const  dirent  =  ArrayPrototypeShift ( this . #bufferedEntries) ; 
194206      if  ( this . #options. recursive  &&  dirent . isDirectory ( ) )  { 
195207        this . readSyncRecursive ( dirent ) ; 
@@ -216,15 +228,13 @@ class Dir {
216228  } 
217229
218230  close ( callback )  { 
219-     // Promise 
220231    if  ( callback  ===  undefined )  { 
221232      if  ( this . #closed ===  true )  { 
222233        return  PromiseReject ( new  ERR_DIR_CLOSED ( ) ) ; 
223234      } 
224235      return  this . #closePromisified( ) ; 
225236    } 
226237
227-     // callback 
228238    validateFunction ( callback ,  'callback' ) ; 
229239
230240    if  ( this . #closed ===  true )  { 
@@ -239,6 +249,11 @@ class Dir {
239249      return ; 
240250    } 
241251
252+     while  ( this . #handlerQueue. length  >  0 )  { 
253+       const  handler  =  ArrayPrototypeShift ( this . #handlerQueue) ; 
254+       handler . handle . close ( ) ; 
255+     } 
256+ 
242257    this . #closed =  true ; 
243258    const  req  =  new  FSReqCallback ( ) ; 
244259    req . oncomplete  =  callback ; 
@@ -254,6 +269,11 @@ class Dir {
254269      throw  new  ERR_DIR_CONCURRENT_OPERATION ( ) ; 
255270    } 
256271
272+     while  ( this . #handlerQueue. length  >  0 )  { 
273+       const  handler  =  ArrayPrototypeShift ( this . #handlerQueue) ; 
274+       handler . handle . close ( ) ; 
275+     } 
276+ 
257277    this . #closed =  true ; 
258278    this . #handle. close ( ) ; 
259279  } 
0 commit comments