diff --git a/src/mixins/async.ts b/src/mixins/async.ts index 625e21b4..abcfee09 100644 --- a/src/mixins/async.ts +++ b/src/mixins/async.ts @@ -37,19 +37,25 @@ export interface AsyncMixin extends Pick(FS: T): Mixin { abstract class AsyncFS extends FS implements AsyncMixin { - /** - * Queue of pending asynchronous operations. - */ - private _queue: AsyncOperation[] = []; - private get _queueRunning(): boolean { - return !!this._queue.length; + async done(): Promise { + await this._promise; } public queueDone(): Promise { - return new Promise(resolve => { - const check = (): unknown => (this._queueRunning ? setTimeout(check) : resolve()); - check(); - }); + return this.done(); + } + + private _promise?: Promise; + + private _async(promise: Promise) { + promise.catch(e => console.error(e.stack)); + + if (!this._promise) { + this._promise = promise; + return; + } + + this._promise = this._promise.then(() => promise); } private _isInitialized: boolean = false; @@ -108,7 +114,7 @@ export function Async(FS: T): Mixin(FS: T): Mixin { this.checkSync(path, 'createFile'); this._sync.createFileSync(path, flag, mode, options); - this.queue('createFile', path, flag, mode, options); + this._async(this.createFile(path, flag, mode, options)); return this.openFileSync(path, flag); } @@ -132,19 +138,19 @@ export function Async(FS: T): Mixin(FS: T): Mixin): void { this.checkSync(path, 'sync'); this._sync.syncSync(path, data, stats); - this.queue('sync', path, data, stats); + this._async(this.sync(path, data, stats)); } public existsSync(path: string): boolean { @@ -177,7 +183,7 @@ export function Async(FS: T): Mixin(FS: T): Mixin { - if (!this._queueRunning) { - return; - } - - const [method, ...args] = this._queue.shift()!; - - // @ts-expect-error 2556 (since ...args is not correctly picked up as being a tuple) - await this[method](...args); - await this._next(); - } - - /** - * @internal - */ - private queue(...op: AsyncOperation) { - this._queue.push(op); - void this._next(); - } - /** * @internal * Patch all async methods to also call their synchronous counterparts unless called from the queue @@ -254,7 +237,7 @@ export function Async(FS: T): Mixin { const result = await originalMethod.apply(this, args); - if (new Error().stack!.includes(`at async ${this.constructor.name}._next`) || !this._isInitialized) return result; + if (new Error().stack!.includes(`at [as ${key}]`) || !this._isInitialized) return result; try { // @ts-expect-error 2556