Last active
March 7, 2024 03:31
-
-
Save pjlsergeant/4afc3c78a8abd1e4e0862b414f5fdb77 to your computer and use it in GitHub Desktop.
Revisions
-
pjlsergeant revised this gist
Mar 7, 2024 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,8 +10,8 @@ before it's ready. const once = new AwaitOnce<string>(); // Only the first call to run() is executed, the other calls just wait // until that's resolved, and return the initially returned result const p1 = once.run( () => delay('slow', 1000) ) ); const p2 = once.run( () => delay('fast', 100) ) ); -
pjlsergeant created this gist
Mar 4, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,46 @@ /* # Why Asynchronously instantiate a singleton only once, even if many calls are made, eg, a handler that lazy-loads a resource, but might be called several times before it's ready. # Synopsis const once = new AwaitOnce<string>(); // Only the first call to run() is executed, the other calls just get back // the same promise the first call had. const p1 = once.run( () => delay('slow', 1000) ) ); const p2 = once.run( () => delay('fast', 100) ) ); const p3 = once.run( () => delay('faster', 10) ) ); const results = await Promise.all( promises ); expect( results ).toEqual(['slow', 'slow', 'slow']); */ export class AwaitOnce<T> { #promise: Promise<T>; #running: boolean = false; #resolve!: (value: T | PromiseLike<T>) => void; #reject!: (reason?: any) => void; constructor() { this.#promise = new Promise<T>( (resolve, reject) => { this.#resolve = resolve; this.#reject = reject; }); } run( fn: () => Promise<T> ) { if ( ! this.#running ) { this.#running = true; fn().then( this.#resolve ).catch( this.#reject ); } return this.#promise; } }