import { Signal } from '../Events/Signal'; export class AsyncLazy { private valueCreated = new Signal(); private isValueCreated = false; private isCreatingValue = false; private value: T | undefined; constructor(private valueFactory: () => Promise) {} public setValueFactory(valueFactory: () => Promise) { this.valueFactory = valueFactory; } public async getValueAsync(): Promise { // If value is already created, return the value directly if (this.isValueCreated) { return Promise.resolve(this.value as T); } // If value is being created, wait until the value is created and then return it. if (this.isCreatingValue) { return new Promise((resolve, reject) => { // Return/result when valueCreated event is triggered. this.valueCreated.on(() => resolve(this.value)); }); } this.isCreatingValue = true; this.value = await this.valueFactory(); this.isCreatingValue = false; this.isValueCreated = true; this.valueCreated.notify(null); return Promise.resolve(this.value); } }