diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/internal/fs/dir.js | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index 175c632fc7..fedd7ff8ed 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -24,8 +24,10 @@ const { const kDirHandle = Symbol('kDirHandle'); const kDirPath = Symbol('kDirPath'); +const kDirBufferedEntries = Symbol('kDirBufferedEntries'); const kDirClosed = Symbol('kDirClosed'); const kDirOptions = Symbol('kDirOptions'); +const kDirReadImpl = Symbol('kDirReadImpl'); const kDirReadPromisified = Symbol('kDirReadPromisified'); const kDirClosePromisified = Symbol('kDirClosePromisified'); @@ -33,6 +35,7 @@ class Dir { constructor(handle, path, options) { if (handle == null) throw new ERR_MISSING_ARGS('handle'); this[kDirHandle] = handle; + this[kDirBufferedEntries] = []; this[kDirPath] = path; this[kDirClosed] = false; @@ -40,7 +43,8 @@ class Dir { encoding: 'utf8' }); - this[kDirReadPromisified] = internalUtil.promisify(this.read).bind(this); + this[kDirReadPromisified] = + internalUtil.promisify(this[kDirReadImpl]).bind(this, false); this[kDirClosePromisified] = internalUtil.promisify(this.close).bind(this); } @@ -49,6 +53,10 @@ class Dir { } read(callback) { + return this[kDirReadImpl](true, callback); + } + + [kDirReadImpl](maybeSync, callback) { if (this[kDirClosed] === true) { throw new ERR_DIR_CLOSED(); } @@ -59,11 +67,22 @@ class Dir { throw new ERR_INVALID_CALLBACK(callback); } + if (this[kDirBufferedEntries].length > 0) { + const [ name, type ] = this[kDirBufferedEntries].splice(0, 2); + if (maybeSync) + process.nextTick(getDirent, this[kDirPath], name, type, callback); + else + getDirent(this[kDirPath], name, type, callback); + return; + } + const req = new FSReqCallback(); req.oncomplete = (err, result) => { if (err || result === null) { return callback(err, result); } + + this[kDirBufferedEntries] = result.slice(2); getDirent(this[kDirPath], result[0], result[1], callback); }; @@ -78,6 +97,11 @@ class Dir { throw new ERR_DIR_CLOSED(); } + if (this[kDirBufferedEntries].length > 0) { + const [ name, type ] = this[kDirBufferedEntries].splice(0, 2); + return getDirent(this[kDirPath], name, type); + } + const ctx = { path: this[kDirPath] }; const result = this[kDirHandle].read( this[kDirOptions].encoding, @@ -90,6 +114,7 @@ class Dir { return result; } + this[kDirBufferedEntries] = result.slice(2); return getDirent(this[kDirPath], result[0], result[1]); } |