I want to chain methods from a class. I have o problems with synchronous methods, but I don't know how to do it with asynchronous methods.
For example, this class:
class Example {
constructor() {
this.val = 0
}
async () {
setTimeout(() => {
this.val += 1
return this
}, 5000)
}
sync () {
this.val += 1
return this
}
check () {
console.log('checker', this.val)
return this
}
}
This works:
new Example().sync().check()
> 1
But this doesn't work:
new Example().async().check()
> TypeError: Cannot read property 'check' of undefined
P.S. I want chaining, not Hell Callbacks.
If you are using
async
functions and methods, you are using promises (I suppose you know them, if not please learn about them before reading on).You should not use
setTimeout
inside of an asynchronous function if you consider waiting for it. Instead, create a promise for the timeout, preferably using a helper function like this:Now you can write your method like you'd really want to:
Of course, as an
async
function it does not return the instance itself, but a promise for it. If you are going to chain, you will have to call it inside of another asynchronous function where you canawait
that promise:What you are looking for will be solved most elegantly by Promises. You'll need to likely install a polyfill, like Bluebird or q.
I would change your async method to:
And your calling code to:
Unfortunately, until ES7 async functions are nailed down, there won't be an elegant way to do this without some form of callback.
I expect that you want to call
check()
after the timeout has expired. The problem is that forks off, and you can't immediately have something available to return.You could pass in
check()
as a callback:... or a promise
... Or you could use ES6 generators
If all you want is
new Example().async().check()
to work, all you need to do isreturn this
after you call setTimeout. Ex:The
return this
inside the timeout isn't necessary, since it'll be executing on its own. It's basically running stand alone at that point.Really, if you want this whole thing to be running async completely, and you're able to control flow of when certain things occur, you need to be using promises to make that happen.