mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
refactor: make Deferred.valueOrThrow
idempotent. (#11657)
This commit is contained in:
parent
6990571d25
commit
93fb2f4ea4
@ -18,70 +18,9 @@ export interface DeferredOptions {
|
||||
* @internal
|
||||
*/
|
||||
export class Deferred<T, V extends Error = Error> {
|
||||
#isResolved = false;
|
||||
#isRejected = false;
|
||||
#value: T | V | TimeoutError | undefined;
|
||||
#resolver: (value: void) => void = () => {};
|
||||
#taskPromise = new Promise<void>(resolve => {
|
||||
this.#resolver = resolve;
|
||||
});
|
||||
#timeoutId: ReturnType<typeof setTimeout> | undefined;
|
||||
#timeoutError: TimeoutError | undefined;
|
||||
|
||||
constructor(opts?: DeferredOptions) {
|
||||
if (opts && opts.timeout > 0) {
|
||||
this.#timeoutError = new TimeoutError(opts.message);
|
||||
this.#timeoutId = setTimeout(() => {
|
||||
this.reject(this.#timeoutError!);
|
||||
}, opts.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
#finish(value: T | V | TimeoutError) {
|
||||
clearTimeout(this.#timeoutId);
|
||||
this.#value = value;
|
||||
this.#resolver();
|
||||
}
|
||||
|
||||
resolve(value: T): void {
|
||||
if (this.#isRejected || this.#isResolved) {
|
||||
return;
|
||||
}
|
||||
this.#isResolved = true;
|
||||
this.#finish(value);
|
||||
}
|
||||
|
||||
reject(error: V | TimeoutError): void {
|
||||
if (this.#isRejected || this.#isResolved) {
|
||||
return;
|
||||
}
|
||||
this.#isRejected = true;
|
||||
this.#finish(error);
|
||||
}
|
||||
|
||||
resolved(): boolean {
|
||||
return this.#isResolved;
|
||||
}
|
||||
|
||||
finished(): boolean {
|
||||
return this.#isResolved || this.#isRejected;
|
||||
}
|
||||
|
||||
value(): T | V | TimeoutError | undefined {
|
||||
return this.#value;
|
||||
}
|
||||
|
||||
async valueOrThrow(): Promise<T> {
|
||||
await this.#taskPromise;
|
||||
if (this.#isRejected) {
|
||||
throw this.#value;
|
||||
}
|
||||
return this.#value as T;
|
||||
}
|
||||
|
||||
static create<R, X extends Error = Error>(
|
||||
opts?: DeferredOptions
|
||||
): Deferred<R> {
|
||||
): Deferred<R, X> {
|
||||
return new Deferred<R, X>(opts);
|
||||
}
|
||||
|
||||
@ -112,4 +51,72 @@ export class Deferred<T, V extends Error = Error> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#isResolved = false;
|
||||
#isRejected = false;
|
||||
#value: T | V | TimeoutError | undefined;
|
||||
// SAFETY: This is ensured by #taskPromise.
|
||||
#resolve!: (value: void) => void;
|
||||
#taskPromise = new Promise<void>(resolve => {
|
||||
this.#resolve = resolve;
|
||||
});
|
||||
#timeoutId: ReturnType<typeof setTimeout> | undefined;
|
||||
#timeoutError: TimeoutError | undefined;
|
||||
|
||||
constructor(opts?: DeferredOptions) {
|
||||
if (opts && opts.timeout > 0) {
|
||||
this.#timeoutError = new TimeoutError(opts.message);
|
||||
this.#timeoutId = setTimeout(() => {
|
||||
this.reject(this.#timeoutError!);
|
||||
}, opts.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
#finish(value: T | V | TimeoutError) {
|
||||
clearTimeout(this.#timeoutId);
|
||||
this.#value = value;
|
||||
this.#resolve();
|
||||
}
|
||||
|
||||
resolve(value: T): void {
|
||||
if (this.#isRejected || this.#isResolved) {
|
||||
return;
|
||||
}
|
||||
this.#isResolved = true;
|
||||
this.#finish(value);
|
||||
}
|
||||
|
||||
reject(error: V | TimeoutError): void {
|
||||
if (this.#isRejected || this.#isResolved) {
|
||||
return;
|
||||
}
|
||||
this.#isRejected = true;
|
||||
this.#finish(error);
|
||||
}
|
||||
|
||||
resolved(): boolean {
|
||||
return this.#isResolved;
|
||||
}
|
||||
|
||||
finished(): boolean {
|
||||
return this.#isResolved || this.#isRejected;
|
||||
}
|
||||
|
||||
value(): T | V | TimeoutError | undefined {
|
||||
return this.#value;
|
||||
}
|
||||
|
||||
#promise: Promise<T> | undefined;
|
||||
valueOrThrow(): Promise<T> {
|
||||
if (!this.#promise) {
|
||||
this.#promise = (async () => {
|
||||
await this.#taskPromise;
|
||||
if (this.#isRejected) {
|
||||
throw this.#value;
|
||||
}
|
||||
return this.#value as T;
|
||||
})();
|
||||
}
|
||||
return this.#promise;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user