提交 36134828 编写于 作者: J Joao Moreno

extract Cache class

上级 538f69b5
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
export default class Cache<T> {
private promise: TPromise<T> = null;
constructor(private task: ()=>TPromise<T>) {}
get(): TPromise<T> {
if (this.promise) {
return this.promise;
}
const promise = this.task();
this.promise = new TPromise<T>((c, e) => promise.done(c, e), () => {
this.promise = null;
promise.cancel();
});
return this.promise;
}
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import Cache from 'vs/base/common/cache';
import { TPromise } from 'vs/base/common/winjs.base';
suite('Cache', () => {
test('simple value', () => {
let counter = 0;
const cache = new Cache(() => TPromise.as(counter++));
return cache.get()
.then(c => assert.equal(c, 0), () => assert.fail())
.then(() => cache.get())
.then(c => assert.equal(c, 0), () => assert.fail());
});
test('simple error', () => {
let counter = 0;
const cache = new Cache(() => TPromise.wrapError(counter++));
return cache.get()
.then(() => assert.fail(), err => assert.equal(err, 0))
.then(() => cache.get())
.then(() => assert.fail(), err => assert.equal(err, 0));
});
test('should retry cancellations', () => {
let counter1 = 0, counter2 = 0;
const cache = new Cache(() => {
counter1++;
return TPromise.timeout(1).then(() => counter2++);
});
assert.equal(counter1, 0);
assert.equal(counter2, 0);
let promise = cache.get();
assert.equal(counter1, 1);
assert.equal(counter2, 0);
promise.cancel();
assert.equal(counter1, 1);
assert.equal(counter2, 0);
promise = cache.get();
assert.equal(counter1, 2);
assert.equal(counter2, 0);
return promise
.then(c => {
assert.equal(counter1, 2);
assert.equal(counter2, 1);
})
.then(() => cache.get())
.then(c => {
assert.equal(counter1, 2);
assert.equal(counter2, 1);
});
});
});
......@@ -11,6 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { marked } from 'vs/base/common/marked/marked';
import { always } from 'vs/base/common/async';
import Event, { Emitter, once } from 'vs/base/common/event';
import Cache from 'vs/base/common/cache';
import { Action } from 'vs/base/common/actions';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, empty, dispose, toDisposable } from 'vs/base/common/lifecycle';
......@@ -22,7 +23,7 @@ import { IViewlet } from 'vs/workbench/common/viewlet';
import { IViewletService } from 'vs/workbench/services/viewlet/common/viewletService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionGalleryService, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
import { ExtensionsInput } from './extensionsInput';
import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension } from './extensions';
......@@ -112,6 +113,9 @@ export class ExtensionEditor extends BaseEditor {
private _highlight: ITemplateData;
private highlightDisposable: IDisposable;
private extensionReadme: Cache<string>;
private extensionManifest: Cache<IExtensionManifest>;
private contentDisposables: IDisposable[] = [];
private transientDisposables: IDisposable[] = [];
private disposables: IDisposable[];
......@@ -130,6 +134,8 @@ export class ExtensionEditor extends BaseEditor {
this._highlight = null;
this.highlightDisposable = empty;
this.disposables = [];
this.extensionReadme = null;
this.extensionManifest = null;
this.disposables.push(viewletService.onDidViewletOpen(this.onViewletOpen, this, this.disposables));
}
......@@ -179,6 +185,9 @@ export class ExtensionEditor extends BaseEditor {
const extension = input.extension;
this.telemetryService.publicLog('extensionGallery:openExtension', extension.telemetryData);
this.extensionReadme = new Cache(() => extension.getReadme());
this.extensionManifest = new Cache(() => extension.getManifest());
const onError = once(domEvent(this.icon, 'error'));
onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables);
this.icon.src = extension.iconUrl;
......@@ -243,8 +252,9 @@ export class ExtensionEditor extends BaseEditor {
}
private openReadme(extension: IExtension) {
return this.loadContents(() => extension.getReadme()
return this.loadContents(() => this.extensionReadme.get()
.then(marked.parse)
.then(renderBody)
.then<void>(body => {
const webview = new WebView(
this.content,
......@@ -252,7 +262,7 @@ export class ExtensionEditor extends BaseEditor {
);
webview.style(this.themeService.getColorTheme());
webview.contents = [renderBody(body)];
webview.contents = [body];
const linkListener = webview.onDidClickLink(link => shell.openExternal(link.toString()));
const themeListener = this.themeService.onDidColorThemeChange(themeId => webview.style(themeId));
......@@ -265,7 +275,7 @@ export class ExtensionEditor extends BaseEditor {
}
private openContributions(extension: IExtension) {
return this.loadContents(() => extension.getManifest()
return this.loadContents(() => this.extensionManifest.get()
.then(manifest => {
this.content.innerHTML = '';
const content = append(this.content, $('div', { class: 'subcontent' }));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册