import { Logger } from 'polar-shared/src/logger/Logger' ; import { NULL_FUNCTION } from 'polar-shared/src/util/Functions' ; import { Latch } from "polar-shared/src/util/Latch" ; const log = Logger . create ( ) ; export class Promises { /**
     * Return the result of ANY of these promises and prefer a successful value
     * but reject if ALL of them fail with the first error.
     *
     * We require at least 1 promise but you can specify up to N
     */ public static async any < T > ( p0 , ... morePromises ) { const promises = [ p0 , ... morePromises ] ; const latch = new Latch < T > ( ) ; const errors = [ ] ; const onError = ( err ) => { errors . push ( err ) ; if ( errors . length === promises . length ) { latch . reject ( errors [ 0 ] ) ; } } ; for ( const promise of promises ) { promise . then ( value => latch . resolve ( value ) ) . catch ( err => onError ( err ) ) ; } return latch . get ( ) ; } /**
     * Execute all the promises in this array in the background and use all the
     * error handler on all of them.
     */ public static executeInBackground ( promises , errorHandler ) { for ( const promise of promises ) { promise . then ( NULL_FUNCTION ) . catch ( err => errorHandler ( err ) ) ; } } param timeout public static async waitFor ( timeout ) { return new Promise < boolean > ( resolve => { setTimeout ( ( ) => { resolve ( true ) ; } , timeout ) ; } ) ; } param val return { Promise < any > } public static of ( val ) { return new Promise ( resolve => { resolve ( val ) ; } ) ; } /**
     * Calls the given callback as a promise which we can await but runs it with
     * the background event loop via timeout to avoid locking up the UI with longer
     * running tasks.
     */ public static async withTimeout < T > ( timeout , callback ) { return new Promise ( ( resolve , reject ) => { setTimeout ( ( ) => { callback ( ) . then ( result => resolve ( result ) ) . catch ( err => reject ( err ) ) ; } , timeout ) ; } ) ; } public static async toVoidPromise ( delegate ) { await delegate ( ) ; } param func public static executeLogged ( func ) { func ( ) . catch ( err => log . error ( "Caught error: " , err ) ) ; } public static requestAnimationFrame ( callback = NULL_FUNCTION ) { return new Promise < boolean > ( resolve => { callback ( ) ; window . requestAnimationFrame ( ( ) => resolve ( true ) ) ; } ) ; } public static toDelayed < T > ( delegate ) { return ( ) => { return new Promise ( ( resolve , reject ) => { try { resolve ( delegate ( ) ) ; } catch ( err ) { reject ( err ) ; } } ) ; } ; } } export interface Completion < T > { readonly resolve : ResolveFunction < T > ; readonly reject : RejectFunction ; } export interface ResolveFunction < T > { ( value ) : void ; } export interface RejectFunction { ( error ) : void ; }