During a code review, I’ve been asked why I do not approve an object with an async constructor.
async constructor() {} // error
}
const f = await new Foo(); // WTF?!
The simple answer is that the language does not support it (Javascript in our case). But simple answers do not convince, so let’s find out why.
Take a look at the following example:
function initSomeData() {
return new Promise(resolve => {
setTimeout(1000, () => resolve({foo: {bar: true}}))
})
}
class AsyncCtrIsBad {
data: {foo: {bar: boolean}};
constructor() {
// async code in our constructor
initSomeData().then(data => data = data);
}
}
const obj = new AsyncCtrIsBad();
console.log(obj.data.foo.bar); // <- the data does not exists yet
What do you think now about the async constructor?
Solution
Use async factory.
// the constructor do what it designed to do
// init object members
constructor(data: {foo: {bar: boolean}}) {
}
}
async function factory() {
const data = await initSomeData();
return new AsyncCtrIsBad(data);
}
const obj = await factory();
console.log(obj.data.foo.bar); // <- Works