debt - adopt more DeferredPromise

This commit is contained in:
Benjamin Pasero 2021-11-21 09:31:09 +01:00
parent 6358042bbc
commit 6825c88670
No known key found for this signature in database
GPG key ID: E6380CC4C8219E65
10 changed files with 62 additions and 61 deletions

View file

@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { DeferredPromise } from 'vs/base/common/async';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { Codicon } from 'vs/base/common/codicons';
import { IMatch } from 'vs/base/common/filters';
@ -101,22 +102,21 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
return true;
}
let symbolProviderRegistryPromiseResolve: (res: boolean) => void;
const symbolProviderRegistryPromise = new Promise<boolean>(resolve => symbolProviderRegistryPromiseResolve = resolve);
const symbolProviderRegistryPromise = new DeferredPromise<boolean>();
// Resolve promise when registry knows model
const symbolProviderListener = disposables.add(DocumentSymbolProviderRegistry.onDidChange(() => {
if (DocumentSymbolProviderRegistry.has(model)) {
symbolProviderListener.dispose();
symbolProviderRegistryPromiseResolve(true);
symbolProviderRegistryPromise.complete(true);
}
}));
// Resolve promise when we get disposed too
disposables.add(toDisposable(() => symbolProviderRegistryPromiseResolve(false)));
disposables.add(toDisposable(() => symbolProviderRegistryPromise.complete(false)));
return symbolProviderRegistryPromise;
return symbolProviderRegistryPromise.p;
}
private doProvideWithEditorSymbols(context: IQuickAccessTextEditorContext, model: ITextModel, picker: IQuickPick<IGotoSymbolQuickPickItem>, token: CancellationToken): IDisposable {

View file

@ -6,7 +6,7 @@
import * as parcelWatcher from '@parcel/watcher';
import { existsSync, unlinkSync } from 'fs';
import { tmpdir } from 'os';
import { RunOnceScheduler } from 'vs/base/common/async';
import { DeferredPromise, RunOnceScheduler } from 'vs/base/common/async';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { Emitter } from 'vs/base/common/event';
@ -244,15 +244,14 @@ export class ParcelWatcherService extends Disposable implements IWatcherService
private startPolling(request: IWatchRequest, pollingInterval: number, restarts = 0): void {
const cts = new CancellationTokenSource();
let parcelWatcherPromiseResolve: () => void;
const instance = new Promise<void>(resolve => parcelWatcherPromiseResolve = resolve);
const instance = new DeferredPromise<void>();
const snapshotFile = join(tmpdir(), `vscode-watcher-snapshot-${generateUuid()}`);
// Remember as watcher instance
const watcher: IWatcher = {
request,
ready: instance,
ready: instance.p,
restarts,
token: cts.token,
stop: async () => {
@ -299,7 +298,7 @@ export class ParcelWatcherService extends Disposable implements IWatcherService
// Signal we are ready now when the first snapshot was written
if (counter === 1) {
parcelWatcherPromiseResolve();
instance.complete();
}
if (cts.token.isCancellationRequested) {
@ -315,19 +314,18 @@ export class ParcelWatcherService extends Disposable implements IWatcherService
private startWatching(request: IWatchRequest, restarts = 0): void {
const cts = new CancellationTokenSource();
let parcelWatcherPromiseResolve: (watcher: parcelWatcher.AsyncSubscription | undefined) => void;
const instance = new Promise<parcelWatcher.AsyncSubscription | undefined>(resolve => parcelWatcherPromiseResolve = resolve);
const instance = new DeferredPromise<parcelWatcher.AsyncSubscription | undefined>();
// Remember as watcher instance
const watcher: IWatcher = {
request,
ready: instance,
ready: instance.p,
restarts,
token: cts.token,
stop: async () => {
cts.dispose(true);
const watcherInstance = await instance;
const watcherInstance = await instance.p;
await watcherInstance?.unsubscribe();
}
};
@ -361,11 +359,11 @@ export class ParcelWatcherService extends Disposable implements IWatcherService
}).then(parcelWatcher => {
this.debug(`Started watching: '${realPath}' with backend '${ParcelWatcherService.PARCEL_WATCHER_BACKEND}' and native excludes '${ignore?.join(', ')}'`);
parcelWatcherPromiseResolve(parcelWatcher);
instance.complete(parcelWatcher);
}).catch(error => {
this.onUnexpectedError(error, watcher);
parcelWatcherPromiseResolve(undefined);
instance.complete(undefined);
});
}

View file

@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { DeferredPromise } from 'vs/base/common/async';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { once } from 'vs/base/common/functional';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
@ -111,10 +112,9 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon
// Pick mode: setup a promise that can be resolved
// with the selected items and prevent execution
let pickPromise: Promise<IQuickPickItem[]> | undefined = undefined;
let pickResolve: Function | undefined = undefined;
let pickPromise: DeferredPromise<IQuickPickItem[]> | undefined = undefined;
if (pick) {
pickPromise = new Promise<IQuickPickItem[]>(resolve => pickResolve = resolve);
pickPromise = new DeferredPromise<IQuickPickItem[]>();
disposables.add(once(picker.onWillAccept)(e => {
e.veto();
picker.hide();
@ -143,7 +143,7 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon
disposables.dispose();
// Resolve pick promise with selected items
pickResolve?.(picker.selectedItems);
pickPromise?.complete(picker.selectedItems.slice(0));
});
// Finally, show the picker. This is important because a provider
@ -153,7 +153,7 @@ export class QuickAccessController extends Disposable implements IQuickAccessCon
// Pick mode: return with promise
if (pick) {
return pickPromise;
return pickPromise?.p;
}
}

View file

@ -5,6 +5,7 @@
import { CrashReporterStartOptions, ipcRenderer } from 'electron';
import { join } from 'path';
import { DeferredPromise } from 'vs/base/common/async';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
@ -176,8 +177,7 @@ class SharedProcessWebWorker extends Disposable {
}
private doInit(): Promise<Worker> {
let readyResolve: (result: Worker) => void;
const readyPromise = new Promise<Worker>(resolve => readyResolve = resolve);
const readyPromise = new DeferredPromise<Worker>();
const worker = new Worker('../../../base/worker/workerMain.js', {
name: `Shared Process Worker (${this.type})`
@ -198,7 +198,7 @@ class SharedProcessWebWorker extends Disposable {
// Lifecycle: Ready
case SharedProcessWorkerMessages.Ready:
readyResolve(worker);
readyPromise.complete(worker);
break;
// Lifecycle: Ack
@ -250,7 +250,7 @@ class SharedProcessWebWorker extends Disposable {
// First message triggers the load of the worker
worker.postMessage('vs/platform/sharedProcess/electron-browser/sharedProcessWorkerMain');
return readyPromise;
return readyPromise.p;
}
private async send(message: ISharedProcessToWorkerMessage, token: CancellationToken, port?: MessagePort): Promise<void> {

View file

@ -43,7 +43,7 @@ import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { mark } from 'vs/base/common/performance';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
import { Promises } from 'vs/base/common/async';
import { DeferredPromise, Promises } from 'vs/base/common/async';
import { IBannerService } from 'vs/workbench/services/banner/browser/bannerService';
import { getVirtualWorkspaceScheme } from 'vs/platform/remote/common/remoteHosts';
import { Schemas } from 'vs/base/common/network';
@ -707,11 +707,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
return undefined;
}
private whenReadyResolve: (() => void) | undefined;
protected readonly whenReady = new Promise<void>(resolve => (this.whenReadyResolve = resolve));
private readonly whenReadyPromise = new DeferredPromise<void>();
protected readonly whenReady = this.whenReadyPromise.p;
private whenRestoredResolve: (() => void) | undefined;
readonly whenRestored = new Promise<void>(resolve => (this.whenRestoredResolve = resolve));
private readonly whenRestoredPromise = new DeferredPromise<void>();
readonly whenRestored = this.whenRestoredPromise.p;
private restored = false;
isRestored(): boolean {
@ -911,11 +911,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
// Await for promises that we recorded to update
// our ready and restored states properly.
Promises.settled(layoutReadyPromises).finally(() => {
this.whenReadyResolve?.();
this.whenReadyPromise.complete();
Promises.settled(layoutRestoredPromises).finally(() => {
this.restored = true;
this.whenRestoredResolve?.();
this.whenRestoredPromise.complete();
});
});
}

View file

@ -30,7 +30,7 @@ import { combinedDisposable, dispose, MutableDisposable, toDisposable } from 'vs
import { Severity, INotificationService } from 'vs/platform/notification/common/notification';
import { toErrorMessage } from 'vs/base/common/errorMessage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Promises, RunOnceWorker } from 'vs/base/common/async';
import { DeferredPromise, Promises, RunOnceWorker } from 'vs/base/common/async';
import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
import { TitleControl } from 'vs/workbench/browser/parts/editor/titleControl';
import { IEditorGroupsAccessor, IEditorGroupView, fillActiveEditorViewState, EditorServiceImpl, IEditorGroupTitleHeight, IInternalEditorOpenOptions, IInternalMoveCopyOptions, IInternalEditorCloseOptions, IInternalEditorTitleControlOptions } from 'vs/workbench/browser/parts/editor/editor';
@ -128,8 +128,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
private readonly containerToolBarMenuDisposable = this._register(new MutableDisposable());
private whenRestoredResolve: (() => void) | undefined;
readonly whenRestored = new Promise<void>(resolve => (this.whenRestoredResolve = resolve));
private readonly whenRestoredPromise = new DeferredPromise<void>();
readonly whenRestored = this.whenRestoredPromise.p;
private isRestored = false;
constructor(
@ -232,7 +232,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
// Signal restored once editors have restored
restoreEditorsPromise.finally(() => {
this.isRestored = true;
this.whenRestoredResolve?.();
this.whenRestoredPromise.complete();
});
// Register Listeners

View file

@ -30,7 +30,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { assertIsDefined } from 'vs/base/common/types';
import { IBoundarySashes } from 'vs/base/browser/ui/grid/gridview';
import { CompositeDragAndDropObserver } from 'vs/workbench/browser/dnd';
import { Promises } from 'vs/base/common/async';
import { DeferredPromise, Promises } from 'vs/base/common/async';
import { findGroup } from 'vs/workbench/services/editor/common/editorGroupFinder';
import { SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
@ -222,11 +222,11 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
private _isReady = false;
get isReady(): boolean { return this._isReady; }
private whenReadyResolve: (() => void) | undefined;
readonly whenReady = new Promise<void>(resolve => (this.whenReadyResolve = resolve));
private readonly whenReadyPromise = new DeferredPromise<void>();
readonly whenReady = this.whenReadyPromise.p;
private whenRestoredResolve: (() => void) | undefined;
readonly whenRestored = new Promise<void>(resolve => (this.whenRestoredResolve = resolve));
private readonly whenRestoredPromise = new DeferredPromise<void>();
readonly whenRestored = this.whenRestoredPromise.p;
get hasRestorableState(): boolean {
return !!this.workspaceMemento[EditorPart.EDITOR_PART_UI_STATE_STORAGE_KEY];
@ -864,12 +864,12 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
this.setupDragAndDropSupport(parent, this.container);
// Signal ready
this.whenReadyResolve?.();
this.whenReadyPromise.complete();
this._isReady = true;
// Signal restored
Promises.settled(this.groups.map(group => group.whenRestored)).finally(() => {
this.whenRestoredResolve?.();
this.whenRestoredPromise.complete();
});
return this.container;

View file

@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { DeferredPromise } from 'vs/base/common/async';
import { Event, Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { IDialog, IDialogResult } from 'vs/platform/dialogs/common/dialogs';
@ -34,11 +35,14 @@ export class DialogsModel extends Disposable implements IDialogsModel {
readonly onDidShowDialog = this._onDidShowDialog.event;
show(dialog: IDialog): IDialogHandle {
let resolver: (value?: IDialogResult) => void;
const promise = new DeferredPromise<IDialogResult | undefined>();
const item: IDialogViewItem = {
args: dialog,
close: (result) => { this.dialogs.splice(0, 1); resolver(result); }
close: result => {
this.dialogs.splice(0, 1);
promise.complete(result);
}
};
this.dialogs.push(item);
@ -46,7 +50,7 @@ export class DialogsModel extends Disposable implements IDialogsModel {
return {
item,
result: new Promise(resolve => { resolver = resolve; })
result: promise.p
};
}
}

View file

@ -9,7 +9,7 @@ import { localize } from 'vs/nls';
import { IDisposable, dispose, DisposableStore, Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IProgressService, IProgressOptions, IProgressStep, ProgressLocation, IProgress, Progress, IProgressCompositeOptions, IProgressNotificationOptions, IProgressRunner, IProgressIndicator, IProgressWindowOptions, IProgressDialogOptions } from 'vs/platform/progress/common/progress';
import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/workbench/services/statusbar/browser/statusbar';
import { RunOnceScheduler, timeout } from 'vs/base/common/async';
import { DeferredPromise, RunOnceScheduler, timeout } from 'vs/base/common/async';
import { ProgressBadge, IActivityService } from 'vs/workbench/services/activity/common/activity';
import { INotificationService, Severity, INotificationHandle } from 'vs/platform/notification/common/notification';
import { Action } from 'vs/base/common/actions';
@ -225,8 +225,7 @@ export class ProgressService extends Disposable implements IProgressService {
// Create a promise that we can resolve as needed
// when the outside calls dispose on us
let promiseResolve: () => void;
const promise = new Promise<void>(resolve => promiseResolve = resolve);
const promise = new DeferredPromise<void>();
this.withWindowProgress({
location: ProgressLocation.Window,
@ -249,16 +248,16 @@ export class ProgressService extends Disposable implements IProgressService {
// Continue to report progress as it happens
const onDidReportListener = progressStateModel.onDidReport(step => reportProgress(step));
promise.finally(() => onDidReportListener.dispose());
promise.p.finally(() => onDidReportListener.dispose());
// When the progress model gets disposed, we are done as well
Event.once(progressStateModel.onWillDispose)(() => promiseResolve());
Event.once(progressStateModel.onWillDispose)(() => promise.complete());
return promise;
return promise.p;
});
// Dispose means completing our promise
return toDisposable(() => promiseResolve());
return toDisposable(() => promise.complete());
};
const createNotification = (message: string, silent: boolean, increment?: number): INotificationHandle => {

View file

@ -19,6 +19,7 @@ import { mark } from 'vs/base/common/performance';
import { ICredentialsProvider } from 'vs/workbench/services/credentials/common/credentials';
import { TunnelProviderFeatures } from 'vs/platform/remote/common/tunnel';
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
import { DeferredPromise } from 'vs/base/common/async';
interface IResourceUriProvider {
(uri: URI): URI;
@ -624,8 +625,7 @@ interface IWorkbench {
* @param options for setting up the workbench
*/
let created = false;
let workbenchPromiseResolve: Function;
const workbenchPromise = new Promise<IWorkbench>(resolve => workbenchPromiseResolve = resolve);
const workbenchPromise = new DeferredPromise<IWorkbench>();
function create(domElement: HTMLElement, options: IWorkbenchConstructionOptions): IDisposable {
// Mark start of workbench
@ -661,14 +661,14 @@ function create(domElement: HTMLElement, options: IWorkbenchConstructionOptions)
let instantiatedWorkbench: IWorkbench | undefined = undefined;
main(domElement, options).then(workbench => {
instantiatedWorkbench = workbench;
workbenchPromiseResolve(workbench);
workbenchPromise.complete(workbench);
});
return toDisposable(() => {
if (instantiatedWorkbench) {
instantiatedWorkbench.shutdown();
} else {
workbenchPromise.then(instantiatedWorkbench => instantiatedWorkbench.shutdown());
workbenchPromise.p.then(instantiatedWorkbench => instantiatedWorkbench.shutdown());
}
});
}
@ -686,7 +686,7 @@ namespace commands {
* @return A promise that resolves to the returned value of the given command.
*/
export async function executeCommand(command: string, ...args: any[]): Promise<unknown> {
const workbench = await workbenchPromise;
const workbench = await workbenchPromise.p;
return workbench.commands.executeCommand(command, ...args);
}
@ -706,7 +706,7 @@ namespace env {
* @returns A promise that resolves to tuples of source and marks.
*/
export async function retrievePerformanceMarks(): Promise<[string, readonly IPerformanceMark[]][]> {
const workbench = await workbenchPromise;
const workbench = await workbenchPromise.p;
return workbench.env.retrievePerformanceMarks();
}
@ -716,7 +716,7 @@ namespace env {
* experience via protocol handler.
*/
export async function getUriScheme(): Promise<string> {
const workbench = await workbenchPromise;
const workbench = await workbenchPromise.p;
return workbench.env.uriScheme;
}
@ -726,7 +726,7 @@ namespace env {
* workbench.
*/
export async function openUri(target: URI): Promise<boolean> {
const workbench = await workbenchPromise;
const workbench = await workbenchPromise.p;
return workbench.env.openUri(target);
}