mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
refactor: change target promises to be deferred (#10191)
This commit is contained in:
parent
354ac3bfc8
commit
5a5e4d46a3
@ -39,7 +39,13 @@ import {ChromeTargetManager} from './ChromeTargetManager.js';
|
|||||||
import {CDPSession, Connection, ConnectionEmittedEvents} from './Connection.js';
|
import {CDPSession, Connection, ConnectionEmittedEvents} from './Connection.js';
|
||||||
import {FirefoxTargetManager} from './FirefoxTargetManager.js';
|
import {FirefoxTargetManager} from './FirefoxTargetManager.js';
|
||||||
import {Viewport} from './PuppeteerViewport.js';
|
import {Viewport} from './PuppeteerViewport.js';
|
||||||
import {OtherTarget, PageTarget, Target, WorkerTarget} from './Target.js';
|
import {
|
||||||
|
InitializationStatus,
|
||||||
|
OtherTarget,
|
||||||
|
PageTarget,
|
||||||
|
Target,
|
||||||
|
WorkerTarget,
|
||||||
|
} from './Target.js';
|
||||||
import {TargetManager, TargetManagerEmittedEvents} from './TargetManager.js';
|
import {TargetManager, TargetManagerEmittedEvents} from './TargetManager.js';
|
||||||
import {TaskQueue} from './TaskQueue.js';
|
import {TaskQueue} from './TaskQueue.js';
|
||||||
import {waitWithTimeout} from './util.js';
|
import {waitWithTimeout} from './util.js';
|
||||||
@ -364,8 +370,8 @@ export class CDPBrowser extends BrowserBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#onDetachedFromTarget = async (target: Target): Promise<void> => {
|
#onDetachedFromTarget = async (target: Target): Promise<void> => {
|
||||||
target._initializedCallback(false);
|
target._initializedPromise.resolve(InitializationStatus.ABORTED);
|
||||||
target._closedCallback();
|
target._isClosedPromise.resolve();
|
||||||
if (await target._initializedPromise) {
|
if (await target._initializedPromise) {
|
||||||
this.emit(BrowserEmittedEvents.TargetDestroyed, target);
|
this.emit(BrowserEmittedEvents.TargetDestroyed, target);
|
||||||
target
|
target
|
||||||
@ -447,7 +453,7 @@ export class CDPBrowser extends BrowserBase {
|
|||||||
return Array.from(
|
return Array.from(
|
||||||
this.#targetManager.getAvailableTargets().values()
|
this.#targetManager.getAvailableTargets().values()
|
||||||
).filter(target => {
|
).filter(target => {
|
||||||
return target._isInitialized;
|
return target._initializedPromise.resolved();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import {createDeferredPromise} from '../util/DeferredPromise.js';
|
|||||||
|
|
||||||
import {CDPSession, Connection} from './Connection.js';
|
import {CDPSession, Connection} from './Connection.js';
|
||||||
import {EventEmitter} from './EventEmitter.js';
|
import {EventEmitter} from './EventEmitter.js';
|
||||||
import {Target} from './Target.js';
|
import {InitializationStatus, Target} from './Target.js';
|
||||||
import {
|
import {
|
||||||
TargetInterceptor,
|
TargetInterceptor,
|
||||||
TargetFactory,
|
TargetFactory,
|
||||||
@ -267,7 +267,8 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const previousURL = target.url();
|
const previousURL = target.url();
|
||||||
const wasInitialized = target._isInitialized;
|
const wasInitialized =
|
||||||
|
target._initializedPromise.value() === InitializationStatus.SUCCESS;
|
||||||
|
|
||||||
target._targetInfoChanged(event.targetInfo);
|
target._targetInfoChanged(event.targetInfo);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import {Protocol} from 'devtools-protocol';
|
|||||||
import type {Browser} from '../api/Browser.js';
|
import type {Browser} from '../api/Browser.js';
|
||||||
import type {BrowserContext} from '../api/BrowserContext.js';
|
import type {BrowserContext} from '../api/BrowserContext.js';
|
||||||
import {Page, PageEmittedEvents} from '../api/Page.js';
|
import {Page, PageEmittedEvents} from '../api/Page.js';
|
||||||
|
import {createDeferredPromise} from '../util/DeferredPromise.js';
|
||||||
|
|
||||||
import {CDPSession} from './Connection.js';
|
import {CDPSession} from './Connection.js';
|
||||||
import {CDPPage} from './Page.js';
|
import {CDPPage} from './Page.js';
|
||||||
@ -28,6 +29,14 @@ import {TaskQueue} from './TaskQueue.js';
|
|||||||
import {debugError} from './util.js';
|
import {debugError} from './util.js';
|
||||||
import {WebWorker} from './WebWorker.js';
|
import {WebWorker} from './WebWorker.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export enum InitializationStatus {
|
||||||
|
SUCCESS = 'success',
|
||||||
|
ABORTED = 'aborted',
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target represents a
|
* Target represents a
|
||||||
* {@link https://chromedevtools.github.io/devtools-protocol/tot/Target/ | CDP target}.
|
* {@link https://chromedevtools.github.io/devtools-protocol/tot/Target/ | CDP target}.
|
||||||
@ -40,35 +49,22 @@ export class Target {
|
|||||||
#browserContext: BrowserContext;
|
#browserContext: BrowserContext;
|
||||||
#session?: CDPSession;
|
#session?: CDPSession;
|
||||||
#targetInfo: Protocol.Target.TargetInfo;
|
#targetInfo: Protocol.Target.TargetInfo;
|
||||||
|
#targetManager: TargetManager;
|
||||||
#sessionFactory: (isAutoAttachEmulated: boolean) => Promise<CDPSession>;
|
#sessionFactory: (isAutoAttachEmulated: boolean) => Promise<CDPSession>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
_initializedPromise: Promise<boolean>;
|
_initializedPromise = createDeferredPromise<InitializationStatus>();
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
_initializedCallback!: (x: boolean) => void;
|
_isClosedPromise = createDeferredPromise<void>();
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_isClosedPromise: Promise<void>;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_closedCallback!: () => void;
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
_isInitialized = false;
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
_targetId: string;
|
_targetId: string;
|
||||||
|
|
||||||
#targetManager: TargetManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
@ -85,12 +81,6 @@ export class Target {
|
|||||||
this.#browserContext = browserContext;
|
this.#browserContext = browserContext;
|
||||||
this._targetId = targetInfo.targetId;
|
this._targetId = targetInfo.targetId;
|
||||||
this.#sessionFactory = sessionFactory;
|
this.#sessionFactory = sessionFactory;
|
||||||
this._initializedPromise = new Promise<boolean>(fulfill => {
|
|
||||||
return (this._initializedCallback = fulfill);
|
|
||||||
});
|
|
||||||
this._isClosedPromise = new Promise<void>(fulfill => {
|
|
||||||
return (this._closedCallback = fulfill);
|
|
||||||
});
|
|
||||||
this._initialize();
|
this._initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,21 +198,15 @@ export class Target {
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
protected _initialize(): void {
|
protected _initialize(): void {
|
||||||
// TODO: refactor to deferred promises.
|
this._initializedPromise.resolve(InitializationStatus.SUCCESS);
|
||||||
this._isInitialized = true;
|
|
||||||
if (this._isInitialized) {
|
|
||||||
this._initializedCallback(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
protected _checkIfInitialized(): void {
|
protected _checkIfInitialized(): void {
|
||||||
if (!this._isInitialized) {
|
if (!this._initializedPromise.resolved()) {
|
||||||
this._isInitialized = true;
|
this._initializedPromise.resolve(InitializationStatus.SUCCESS);
|
||||||
this._initializedCallback(true);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,12 +293,11 @@ export class PageTarget extends Target {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override _checkIfInitialized(): void {
|
override _checkIfInitialized(): void {
|
||||||
if (this._isInitialized) {
|
if (this._initializedPromise.resolved()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._isInitialized = this._getTargetInfo().url !== '';
|
if (this._getTargetInfo().url !== '') {
|
||||||
if (this._isInitialized) {
|
this._initializedPromise.resolve(InitializationStatus.SUCCESS);
|
||||||
this._initializedCallback(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ export interface DeferredPromise<T> extends Promise<T> {
|
|||||||
resolved: () => boolean;
|
resolved: () => boolean;
|
||||||
resolve: (value: T) => void;
|
resolve: (value: T) => void;
|
||||||
reject: (reason?: unknown) => void;
|
reject: (reason?: unknown) => void;
|
||||||
|
value: () => T | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,6 +33,7 @@ export function createDeferredPromise<T>(
|
|||||||
): DeferredPromise<T> {
|
): DeferredPromise<T> {
|
||||||
let isResolved = false;
|
let isResolved = false;
|
||||||
let isRejected = false;
|
let isRejected = false;
|
||||||
|
let _value: T | undefined;
|
||||||
let resolver: (value: T) => void;
|
let resolver: (value: T) => void;
|
||||||
let rejector: (reason?: unknown) => void;
|
let rejector: (reason?: unknown) => void;
|
||||||
const taskPromise = new Promise<T>((resolve, reject) => {
|
const taskPromise = new Promise<T>((resolve, reject) => {
|
||||||
@ -57,6 +59,7 @@ export function createDeferredPromise<T>(
|
|||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
}
|
}
|
||||||
isResolved = true;
|
isResolved = true;
|
||||||
|
_value = value;
|
||||||
resolver(value);
|
resolver(value);
|
||||||
},
|
},
|
||||||
reject: (err?: unknown) => {
|
reject: (err?: unknown) => {
|
||||||
@ -64,5 +67,8 @@ export function createDeferredPromise<T>(
|
|||||||
isRejected = true;
|
isRejected = true;
|
||||||
rejector(err);
|
rejector(err);
|
||||||
},
|
},
|
||||||
|
value: () => {
|
||||||
|
return _value;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user