export class TaskTracker { private pendingTasks = 0; public get hasPendingTasks() { return this.pendingTasks !== 0; } public register any>(task: F) { return (...args: Parameters) => { this.pendingTasks++; const result = task(...args); if (result instanceof Promise) { void this.unwrap(result); } else { this.pendingTasks--; } return result; }; } public async await(pollInterval = 200) { while (this.pendingTasks !== 0) { await this.sleep(pollInterval); } } private sleep(time = 200) { return new Promise(resolve => setTimeout(resolve, time)); } private unwrap(promise: Promise) { return promise .then(() => { this.pendingTasks--; }) .catch(e => { this.pendingTasks--; throw e; }); } }