From 563785ea74c34a1370147f673c2ffa6a85fcf86c Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Thu, 17 Feb 2022 08:08:01 -0800 Subject: [PATCH] Create a fast path for children that resolve sync (#143162) Ref #140883 --- src/vs/base/browser/ui/tree/asyncDataTree.ts | 36 +++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index f0224d3e4e7..5f1b89e1e03 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -20,6 +20,7 @@ import { Iterable } from 'vs/base/common/iterator'; import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle'; import { ScrollEvent } from 'vs/base/common/scrollable'; import { IThemable } from 'vs/base/common/styler'; +import { isIterable } from 'vs/base/common/types'; interface IAsyncDataTreeNode { element: TInput | T; @@ -764,15 +765,19 @@ export class AsyncDataTree implements IDisposable if (!node.hasChildren) { childrenPromise = Promise.resolve(Iterable.empty()); } else { - const slowTimeout = timeout(800); + const children = this.doGetChildren(node); + if (isIterable(children)) { + childrenPromise = Promise.resolve(children); + } else { + const slowTimeout = timeout(800); - slowTimeout.then(() => { - node.slow = true; - this._onDidChangeNodeSlowState.fire(node); - }, _ => null); + slowTimeout.then(() => { + node.slow = true; + this._onDidChangeNodeSlowState.fire(node); + }, _ => null); - childrenPromise = this.doGetChildren(node) - .finally(() => slowTimeout.cancel()); + childrenPromise = children.finally(() => slowTimeout.cancel()); + } } try { @@ -796,21 +801,20 @@ export class AsyncDataTree implements IDisposable } } - private doGetChildren(node: IAsyncDataTreeNode): Promise> { + private doGetChildren(node: IAsyncDataTreeNode): Promise> | Iterable { let result = this.refreshPromises.get(node); if (result) { return result; } - - result = createCancelablePromise(async () => { - const children = await this.dataSource.getChildren(node.element!); + const children = this.dataSource.getChildren(node.element!); + if (isIterable(children)) { return this.processChildren(children); - }); - - this.refreshPromises.set(node, result); - - return result.finally(() => { this.refreshPromises.delete(node); }); + } else { + result = createCancelablePromise(async () => this.processChildren(await children)); + this.refreshPromises.set(node, result); + return result.finally(() => { this.refreshPromises.delete(node); }); + } } private _onDidChangeCollapseState({ node, deep }: ICollapseStateChangeEvent | null, any>): void {