From fb318f0be37fbea7b4ea0a4c82c1fb221d3275c2 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 4 Apr 2016 12:15:48 +0200 Subject: [PATCH] proper delayed paging --- src/vs/base/common/paging.ts | 39 ++++++++++++++----- .../parts/quickopen/common/quickOpenPaging.ts | 14 ++----- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/vs/base/common/paging.ts b/src/vs/base/common/paging.ts index a0ee4f194b5..ee6d1b28ddc 100644 --- a/src/vs/base/common/paging.ts +++ b/src/vs/base/common/paging.ts @@ -6,6 +6,7 @@ 'use strict'; import { TPromise } from 'vs/base/common/winjs.base'; +import { ArraySet } from 'vs/base/common/set'; export interface IPager { firstPage: T[]; @@ -17,6 +18,7 @@ export interface IPager { interface IPage { isResolved: boolean; promise: TPromise; + promiseIndexes: ArraySet; elements: T[]; } @@ -26,13 +28,13 @@ export class PagedModel { get length(): number { return this.pager.total; } - constructor(private pager: IPager) { - this.pages = [{ isResolved: true, promise: null, elements: pager.firstPage.slice() }]; + constructor(private pager: IPager, private pageTimeout: number = 500) { + this.pages = [{ isResolved: true, promise: null, promiseIndexes: new ArraySet(), elements: pager.firstPage.slice() }]; const totalPages = Math.ceil(pager.total / pager.pageSize); for (let i = 0, len = totalPages - 1; i < len; i++) { - this.pages.push({ isResolved: false, promise: null, elements: [] }); + this.pages.push({ isResolved: false, promise: null, promiseIndexes: new ArraySet(), elements: [] }); } } @@ -60,14 +62,33 @@ export class PagedModel { } if (!page.promise) { - page.promise = this.pager.getPage(pageIndex).then(elements => { - page.elements = elements; - page.isResolved = true; - page.promise = null; - }); + page.promise = TPromise.timeout(this.pageTimeout) + .then(() => this.pager.getPage(pageIndex)) + .then(elements => { + page.elements = elements; + page.isResolved = true; + page.promise = null; + }, err => { + page.isResolved = false; + page.promise = null; + return TPromise.wrapError(err); + }); } - return page.promise.then(() => page.elements[indexInPage]); + return new TPromise((c, e) => { + page.promiseIndexes.set(index); + page.promise.done(() => c(page.elements[indexInPage])); + }, () => { + if (!page.promise) { + return; + } + + page.promiseIndexes.unset(index); + + if (page.promiseIndexes.elements.length === 0) { + page.promise.cancel(); + } + }); } } diff --git a/src/vs/base/parts/quickopen/common/quickOpenPaging.ts b/src/vs/base/parts/quickopen/common/quickOpenPaging.ts index 031fc36b36b..d640b423e17 100644 --- a/src/vs/base/parts/quickopen/common/quickOpenPaging.ts +++ b/src/vs/base/parts/quickopen/common/quickOpenPaging.ts @@ -43,17 +43,11 @@ class PagedRenderer implements IRenderer { return this.renderer.renderElement(this.model.get(index), templateId, data.data); } - let didUnrender = false; - data.disposable = { dispose: () => didUnrender = true }; - this.renderer.renderPlaceholder(index, templateId, data.data); - - this.model.resolve(index).done(entry => { - if (didUnrender) { - return; - } + const promise = this.model.resolve(index); + data.disposable = { dispose: () => promise.cancel() }; - this.renderer.renderElement(entry, templateId, data.data); - }); + this.renderer.renderPlaceholder(index, templateId, data.data); + promise.done(entry => this.renderer.renderElement(entry, templateId, data.data)); } disposeTemplate(templateId: string, data: IStubTemplateData): void { -- GitLab