Try to avoid extra promise chaining for posting into a webview

This moves the `<webview>` based webviews to use a queue of pending messages while the webview itself is being prepared. This lets us avoid calling `.then` if the webview has already been resolved
This commit is contained in:
Matt Bierner 2021-03-09 18:09:59 -08:00
parent cbacbe647c
commit a9087e9d0a

View file

@ -44,11 +44,13 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
private _findStarted: boolean = false;
private readonly _resourceRequestManager: WebviewResourceRequestManager;
private _messagePromise = Promise.resolve();
private readonly _focusDelayer = this._register(new ThrottledDelayer(10));
private _elementFocusImpl!: (options?: FocusOptions | undefined) => void;
private _isWebviewReadyForMessages = false;
private readonly _pendingMessages: Array<{ channel: string, data: any }> = [];
constructor(
id: string,
options: WebviewOptions,
@ -81,6 +83,16 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
this._myLogService.debug(`Webview(${this.id}): init`);
this._resourceRequestManager = this._register(instantiationService.createInstance(WebviewResourceRequestManager, id, extension, this.content.options));
this._resourceRequestManager.ensureReady()
.then(() => {
this._isWebviewReadyForMessages = true;
while (this._pendingMessages.length) {
const { channel, data } = this._pendingMessages.shift()!;
this._myLogService.debug(`Webview(${this.id}): did post message on '${channel}'`);
this.element?.send(channel, data);
}
});
this._register(addDisposableListener(this.element!, 'dom-ready', once(() => {
this._register(ElectronWebviewBasedWebview.getWebviewKeyboardHandler(configurationService, mainProcessService).add(this.element!));
@ -210,13 +222,13 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
protected async doPostMessage(channel: string, data?: any): Promise<void> {
this._myLogService.debug(`Webview(${this.id}): will post message on '${channel}'`);
if (!this._isWebviewReadyForMessages) {
this._pendingMessages.push({ channel, data });
return;
}
this._messagePromise = this._messagePromise
.then(() => this._resourceRequestManager.ensureReady())
.then(() => {
this._myLogService.debug(`Webview(${this.id}): did post message on '${channel}'`);
return this.element?.send(channel, data);
});
this._myLogService.debug(`Webview(${this.id}): did post message on '${channel}'`);
this.element?.send(channel, data);
}
public focus(): void {