import { PromiseBase , TSDNPromise } from "./Promise" ; import { Closure } from "typescript-dotnet-core/FunctionTypes" ; import ICancellable from "typescript-dotnet-threading/ICancellable" ; import defer from "typescript-dotnet-threading/defer" ; import ArgumentNullException from "typescript-dotnet-core/Exceptions/ArgumentNullException" ; const VOID0 = void 0 ; /**
 * A promise that waits for the first then to trigger the resolver.
 */ export class LazyPromise < T > extends TSDNPromise < T > { constructor ( private _resolver ) { super ( ) ; if ( ! _resolver ) throw new ArgumentNullException ( "resolver" ) ; this . _resolvedCalled = true ; } protected _onDispose ( ) { super . _onDispose ( ) ; this . _resolver = VOID0 ; } private _onThen ( ) { const r = this . _resolver ; if ( r ) { this . _resolver = VOID0 ; this . _resolvedCalled = false ; this . resolveUsing ( r ) ; } } thenSynchronous < TFulfilled = T , TRejected = never > ( onFulfilled , onRejected ? ) { this . _onThen ( ) ; return super . thenSynchronous ( onFulfilled , onRejected ) ; } doneNow ( onFulfilled , onRejected ? ) { this . _onThen ( ) ; super . doneNow ( onFulfilled , onRejected ) ; } param milliseconds returns delayFromNow ( milliseconds = 0 ) { this . throwIfDisposed ( ) ; if ( ! this . _resolver || this . isSettled ) return super . delayFromNow ( milliseconds ) ; let pass ; let timedOut = false ; let timeout = defer ( ( ) => { timedOut = true ; if ( pass ) pass ( ) ; } , milliseconds ) ; return new LazyPromise < T > ( ( resolve , reject ) => { pass = ( ) => { this . doneNow ( v => resolve ( v ) , e => reject ( e ) ) ; timeout . dispose ( ) ; timeout = VOID0 ; pass = VOID0 ; } ; if ( timedOut ) pass ( ) ; } ) ; } param milliseconds returns delayAfterResolve ( milliseconds = 0 ) { this . throwIfDisposed ( ) ; if ( ! this . _resolver || this . isSettled ) return super . delayAfterResolve ( milliseconds ) ; let pass ; let timeout ; let finalize = ( ) => { if ( timeout ) { timeout . dispose ( ) ; timeout = VOID0 ; } if ( pass ) pass ( ) ; finalize = VOID0 ; } ; { let detector = ( ) => { if ( finalize ) timeout = defer ( finalize , milliseconds ) ; } ; super . doneNow ( detector , detector ) ; detector = < any > null ; } return new LazyPromise < T > ( ( resolve , reject ) => { if ( this . isPending ) { this . doneNow ( v => defer ( ( ) => resolve ( v ) , milliseconds ) , e => defer ( ( ) => reject ( e ) , milliseconds ) ) ; finalize ( ) ; } else { pass = ( ) => { this . doneNow ( v => resolve ( v ) , e => reject ( e ) ) ; } ; if ( ! finalize ) pass ( ) ; } } ) ; } } export default LazyPromise ;