export class AbortablePromise < TResult , TError > implements Promise < TResult > { public static ABORT_ERROR = 'AbortError' ; public readonly [ Symbol . toStringTag ] : string ; private isPending : boolean ; private isAborted : boolean ; private promise : Promise < TResult > ; private resolve : ( result : TResult ) => void ; private reject : ( error : any ) => void ; constructor ( promise ) { this . isPending = true ; this . isAborted = false ; this . promise = new Promise < TResult > ( ( resolve , reject ) => { this . resolve = resolve ; this . reject = reject ; promise . then ( ( result ) => { if ( this . isAborted ) { reject ( AbortablePromise . ABORT_ERROR ) ; } else { resolve ( result ) ; } } ) . catch ( ( error ) => { if ( ! this . isAborted ) { reject ( error ) ; } } ) ; } ) ; this . promise . finally ( ( ) => { this . isPending = false ; } ) . catch ( ( error ) => { if ( error !== AbortablePromise . ABORT_ERROR ) { throw error ; } } ) ; } public then < TResult1 = TResult , TResult2 = never > ( onfulfilled ? , onrejected ? ) { return this . promise . then ( onfulfilled , onrejected ) ; } public catch < TCaught = never > ( onrejected ? ) { return this . promise . catch ( onrejected ) ; } public finally ( handler ) { return this . promise . finally ( handler ) ; } public abort ( ) { this . isAborted = true ; this . isPending = false ; this . reject ( AbortablePromise . ABORT_ERROR ) ; } public get isExecuting ( ) { return this . isPending ; } public get isDone ( ) { return ! this . isPending ; } }