I'm using loopback 3
to build a REST service, and I want to use the async/await instead of having to use the callbacks. So instead of doing that:
MyModel.myFunction = (callback) => {
MyModel.find({where: {id: 2}}, (e, data) => {
if (e) return callback(e);
callback(null, data);
});
};
I would greatly prefer to do:
MyModel.myFunction = async (callback) => {
try {
const data = await MyModel.find({where: {id: 2}});
callback(null, data);
} catch (e) {
console.error(e);
callback(e);
}
};
The callback approach works perfectly - async/await however gives numerous errors:
UnhandledPromiseRejectionWarning: Error: Callback was already called.
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
What's wrong? I cannot get through this issue.
When you use await , you expect JavaScript to pause execution until the awaited promise gets resolved. This means await s in a for-loop should get executed in series. The result is what you'd expect. This behaviour works with most loops (like while and for-of loops)…
The async-await syntax is just syntactic sugar on top of the promises API, the async tag on a function simply lets javascript know that this function would return a promise and the awaits inside the functions tell the interpreter to stay on this line of code inside this function call till the promise called on that ...
No, await won't block the looping.
In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() .
Looks like I was simply mixing two concepts, this is the solution:
MyModel.myFunction = async (callback) => {
try {
const data = await MyModel.find({where: {id: 2}});
return Promise.resolve(data);
} catch (e) {
console.error(e);
return Promise.reject(e);
}
};
Some refactoring:
MyModel.myFunction = async () => {
try {
const data = await MyModel.find({where: {id: 2}});
return data; // it's enough as the async means it returns a promise
} catch (e) {
console.error(e);
throw e;
}
};
This one in case if you don't need to log an error (loopback error handler logs it instead of you):
MyModel.myFunction = async () => {
return MyModel.find({where: {id: 2}});
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With