Skip to content

Instantly share code, notes, and snippets.

@fulminmaxi
Created May 9, 2020 20:17
Show Gist options
  • Save fulminmaxi/ee89e1d9b48956aebff1dd7dbe25dad1 to your computer and use it in GitHub Desktop.
Save fulminmaxi/ee89e1d9b48956aebff1dd7dbe25dad1 to your computer and use it in GitHub Desktop.
Async Constructor Helper in JavaScript
function WillBe(Class){
return class AsyncConstructor extends Class {
constructor(...values) {
super(...values);
this.willBe = (async () => {
let resolvedThis = await promiseAllObj(this);
//Remove this.willBe to avoid circular promises
return Object.keys(resolvedThis)
.reduce((acc,key) => (key === 'willBe'
? acc
: {...acc, [`${key}`]: resolvedThis[key]}
), {})
})()
}
get init(){
return this.willBe.then(instance => {
this.value = instance;
return this;
})
}
}
}
const Asyncio = WillBe(class Bar {
constructor(foo, baz) {
this.foo = foo;
this.bar = fetchBar()
this.baz = baz;
}
})
const example = new Asyncio('sync foo', 'sync baz')
// logs 'sync foo'
console.log(example.foo)
// logs 'sync baz'
console.log(example.baz)
async function main(){
let {value} = await example.init
// logs {foo: 'sync foo', bar: 'async bar', baz: 'sync baz'
console.log(value)
}
main()
// ********Helpers**************
function promiseAllObj(obj){
return Promise.all(
Object.entries(obj)
.map(([key, val]) =>
val instanceof Promise
? val.then(res => [key, res])
: new Promise(res => res([key,val])))
)
.then(Object.fromEntries)
}
function fetchBar() {
return new Promise((res,rej) => setTimeout(() => res('async bar'), 2000))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment