diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index f7a544b719b28..5dd2aa0eae61f 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -416,6 +416,19 @@ class ExtHostTreeView extends Disposable { })); } + private _loadingPromise: Promise | undefined; + private trackAsLoading(promise: Promise): Promise { + const chainedPromise = this._loadingPromise ? this._loadingPromise.finally(() => promise) : promise; + const last = chainedPromise.catch(() => { }).finally(() => { + if (this._loadingPromise === last) { + this._loadingPromise = undefined; + } + }); + this._loadingPromise = last; + + return promise; + } + async getChildren(parentHandle: TreeItemHandle | Root): Promise { const parentElement = parentHandle ? this.getExtensionElement(parentHandle) : undefined; if (parentHandle && !parentElement) { @@ -426,7 +439,7 @@ class ExtHostTreeView extends Disposable { let childrenNodes: TreeNode[] | undefined = this.getChildrenNodes(parentHandle); // Get it from cache if (!childrenNodes) { - childrenNodes = await this.fetchChildrenNodes(parentElement); + childrenNodes = await this.trackAsLoading(this.fetchChildrenNodes(parentElement)); } return childrenNodes ? childrenNodes.map(n => n.item) : undefined; @@ -698,7 +711,11 @@ class ExtHostTreeView extends Disposable { private _refreshCancellationSource = new CancellationTokenSource(); - private refresh(elements: (T | Root)[]): Promise { + private async refresh(elements: (T | Root)[]): Promise { + while (this._loadingPromise) { + await this._loadingPromise; + } + const hasRoot = elements.some(element => !element); if (hasRoot) { // Cancel any pending children fetches @@ -713,7 +730,7 @@ class ExtHostTreeView extends Disposable { return this.refreshHandles(handlesToRefresh); } } - return Promise.resolve(undefined); + return undefined; } private getHandlesToRefresh(elements: T[]): TreeItemHandle[] {