/* -------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ 'use strict'; export interface ITask { (): T; } export class Delayer { public defaultDelay: number; private timeout: NodeJS.Timer; private completionPromise: Promise; private onSuccess: (value?: T | Thenable) => void; private task: ITask; 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; var result = this.task(); this.task = null; return result; }); } if (delay >= 0 || this.timeout === null) { this.timeout = setTimeout(() => { this.timeout = null; this.onSuccess(null); }, delay >= 0 ? delay : this.defaultDelay); } return this.completionPromise; } public forceDelivery(): T { if (!this.completionPromise) { return null; } this.cancelTimeout(); let result: T = this.task(); this.completionPromise = null; this.onSuccess = null; this.task = null; 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; } } }