Anticipated FAQ:
- Yes, I know what a Promise is.
- No, I can't simply move the init logic to the constructor. It needs to be called in the
initMethod
because theinitMethod
is a hook that needs to be called at a certain time.
Sorry, it's just that I saw some similar questions marked as "duplicate", so I wanted to put these FAQ at the top.
Question
My issue is the following race condition:
class Service {
private x: string | null = null;
initMethod() {
this.x = 'hello';
}
async methodA() {
return this.x.length;
}
}
const service = new Service();
setTimeout(() => service.initMethod(), 1000);
service.methodA().catch(console.log);
TypeError: Cannot read properties of null (reading 'length')
at Service.methodA (<anonymous>:15:19)
at <anonymous>:20:9
at dn (<anonymous>:16:5449)
I need something like a Promise whose settled value can be set from another part of the code. Something like:
class Service {
private x: SettablePromise<string> = new SettablePromise();
initMethod() {
this.x.set('hello');
}
async methodA() {
return (await this.x).length;
}
}
const service = new Service();
setTimeout(() => service.initMethod(), 1000);
service.methodA().catch(console.log);
The best I can come up with is to make a class that polls a value until it turns non-null. I'm hoping there's something smarter. I don't want to have to fine-tune a poll interval.
Edits
Sorry for the initial confusing example. The race condition is that methodA
can be called before initMethod
.
There was also an unnecessary async
in the initMethod
. I just made it async
because the real method it was based on is async
.