/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ export interface ITask { (): T; } export class Delayer { public defaultDelay: number; private timeout: any; // Timer private completionPromise: Promise | null; private onSuccess: ((value: T | PromiseLike | undefined) => void) | null; private task: ITask | null; constructor(defaultDelay: number) { this.defaultDelay = defaultDelay; this.timeout = null; this.completionPromise = null; this.onSuccess = null; this.task = null; } public trigger(task: ITask, delay: number = this.defaultDelay): Promise { this.task = task; if (delay >= 0) { this.cancelTimeout(); } if (!this.completionPromise) { this.completionPromise = new Promise((resolve) => { this.onSuccess = resolve; }).then(() => { this.completionPromise = null; this.onSuccess = null; let result = this.task!(); this.task = null; return result; }); } if (delay >= 0 || this.timeout === null) { this.timeout = setTimeout(() => { this.timeout = null; this.onSuccess!(undefined); }, delay >= 0 ? delay : this.defaultDelay); } return this.completionPromise; } public forceDelivery(): Promise | null { if (!this.completionPromise) { return null; } this.cancelTimeout(); let result = this.completionPromise; this.onSuccess!(undefined); return result; } public isTriggered(): boolean { return this.timeout !== null; } public cancel(): void { this.cancelTimeout(); this.completionPromise = null; } private cancelTimeout(): void { if (this.timeout !== null) { clearTimeout(this.timeout); this.timeout = null; } } }