I have an instance of a class:
let myInstance = new MyObject();
that looks like this:
export default class MyObject () {
constructor () {}
methodOne () {
// Do stuff …
return this;
}
async methodTwo () {
let db_query = await Connection.query('<DATABASE QUERY>');
return this;
}
methodThree () {
// Do stuff …
return this;
}
// etc.
}
This way I can chain methods on the instance:
myInstance
.methodOne()
.methodTwo()
.methodThree()
How can I make sure that methodTwo
won’t return (this
) until the async
/await
is resolved?
Doing something like this (won’t work):
let db_query = await Connection.query('<DATABASE QUERY>');
db_query
.then(() => {
return this:
})
Note: myInstance
is itself wrapped in an async
/await
method.
2
Answers
methodTwo
returns a promise, like allasync
functions do. It’s a promise that will be fulfilled withthis
, or rejected if the operation it awaits rejects. There’s nothing you can do to makemethodTwo
wait synchronously for the asynchronous result fromConnection.query
. JavaScript’s run-to-completion, one-active-thread-per-realm semantics don’t allow that.Since
methodTwo
returns a promise, to use the chaining, you’d have to await the result ofmethodTwo
:…which isn’t…beautiful, but isn’t too bad. 🙂 Or if you’re doing this where you can’t use
await
, you’d needthen
(at minumum, probably alsocatch
):…which is probably even less beautiful. 🙂
This is just a fundamental aspect of asynchronous operations in JavaScript.
You could make
methodTwo
notasync
and have it returnthis
before theConnection.query
operation completes, but I suspect you don’t want to do that.Things like that are done with
Proxy
. Here’s a very simple example without multiple chaining: