interface QueueObject { startPromise : ( ) => Promise < void > ; } /**
 * Helper utility that processes promises one by one in the order they arrive,
 * with an optional time-out value.
 */ export class AsyncQueue { private readonly _promiseQueue : QueueObject [ ] = [ ] ; private _promiseInProgress = false ; public async addToQueue < T = any > ( promiseGenerator ) { return await new Promise ( ( resolve , reject ) => { const startPromise = async ( ) : Promise < void > => { this . _promiseInProgress = true ; try { const resp = await promiseGenerator ( ) ; resolve ( resp ) ; } catch ( err ) { reject ( err ) ; } finally { this . _notifyUploadFinish ( ) ; } } ; if ( ! this . _promiseInProgress ) { startPromise ( ) ; return ; } const queueObject = { startPromise , } ; this . _promiseQueue . push ( queueObject ) ; } ) ; } private _notifyUploadFinish ( ) { this . _promiseInProgress = false ; const oldestPromise = this . _promiseQueue . shift ( ) ; if ( oldestPromise !== undefined ) { oldestPromise . startPromise ( ) ; } } }