export interface QueueObject { animate: (...args: any[]) => Promise; context: any; args?: any[]; onError?: (error: any) => void; } export class AnimationQueue { private __running = false; private __queueObjects: QueueObject[] = []; push(o: QueueObject): void { if (this.__running) { this.__queueObjects.push(o); } else { this.__running = true; this.__animate(o); } } clear(): void { this.__queueObjects = []; } private __animate(o: QueueObject): void { const __this = this; try { if (!o.animate) { return; } o.animate .apply(o.context, !!o.args ? o.args : []) .then(() => { if (0 < __this.__queueObjects.length) { const __o = __this.__queueObjects.shift(); if (!!__o) { __this.__animate.call(__this, __o); } else { __this.__running = false; } } }) .catch(reason => { if (!!o.onError) { o.onError.apply(o.context, [reason]); } }); } catch (e) { if (!!o.onError) { o.onError.apply(o.context, [e]); } } } }