How to properly implement mongodb async/await inside a promise?

Multi tool use
How to properly implement mongodb async/await inside a promise?
I've read that having an async inside a Promise
is anti-pattern for async/await. The code below works, but I am curious how else to achieve the same result without having async
in Promise
.
Promise
async
Promise
If I remove it, the linter would tell how I can't use await in my mongodb query. If I remove the await in the mongodb query, then it wouldn't wait for the result.
export const getEmployees = (companyId) => {
return new Promise(async (resolve, reject) => {
const employees = await Employees.find(
{ companyId },
);
// other logic here...
resolve({
employees,
});
});
Thanks.
2 Answers
2
async
functions automatically return Promise
s already, which resolve with whatever expression is eventually return
ed. Simply make getEmployees
an async
function:
async
Promise
return
getEmployees
async
export const getEmployees = async (companyId) => {
const employees = await Employees.find(
{ companyId },
);
// other logic here...
return { employees };
};
(but make sure to catch
in the consumer of getEmployees
just in case there's an error)
catch
getEmployees
let employees; try { employees = await getEmployees(companyId); } catch(e) { /* handle */ }
@Woppi - One of the rules of promises (and thus,
async
/await
, since async
/await
is "just" syntactic sugar for promise creation and consumption) is: You must either handle errors, or propagate the promise to something that handles errors (and so on up the chain; something, somewhere must handle the error). So if you're using getEmployees
in another async
function, that other function's caller must either handle (via try
/catch
) or propagate (by returning a promise that derives from the getEmployees
promise).– T.J. Crowder
Jun 30 at 11:49
async
await
async
await
getEmployees
async
try
catch
getEmployees
@Woppi - You don't need packages for it. Just handle errors. Particularly with
async
/await
, it's trivial.– T.J. Crowder
Jun 30 at 12:00
async
await
@AnthonyWinzlet -
async
/await
are defined by the latest JavaScript spec (ES2018), which was just released, and are supported in the most recent versions of Chrome, Firefox, Edge, and Node.js. More: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…– T.J. Crowder
Jun 30 at 13:20
async
await
@T.J.Crowder got it... thank you very much for the clarification
– Anthony Winzlet
Jun 30 at 13:21
As @CertainPerformance answered, that is perfect way to retrieve data from mongoDB using async/await, I would like to add some more information about how to handle errors in this case for correctness of the system, and better error handle to return better status to the client about his request.
I'd say it , you usually want to catch all exceptions from async/await call.
try {
const employees = await Employees.find({
companyId
});
// You can add more logic here before return the data.
return {
employees
};
} catch (error) {
console.error(error);
}
Now let's check the ways we can handle our errors that might occur.
This is the most common way to handle errors in those cases and most elegant way in my opinion.
Handle error inside error scope:
export const getEmployees = async (companyId) => {
try {
const employees = await Employees.find({
companyId
});
// You can add more logic here before return the data.
return {
employees
};
} catch (error) {
console.error(error);
}
};
Assign a default value to the variable in the catch block:
export const getEmployees = async (companyId) => {
let employees;
try {
employees = await Employees.find({
companyId
});
// You can add more logic here before return the data.
employees = employees;
} catch (error) {
console.error(error);
}
if (employees) { // We received the data successfully.
console.log(employees)
// Business logic goes here.
}
return employees;
};
Inspect error instance and act accordingly:
export const getEmployees = async (companyId) => {
try {
const employees = await Employees.find({
companyId
});
// You can add more logic here before return the data.
return {
employees
};
} catch (error) {
if (error instanceof ConnectionError) {
console.error(error);
} else {
throw error;
}
}
};
Some more explanations about async await and more useful methods that you can find in those answers.
How run async / await in parallel in Javascript
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Mm, the consumer is an async function too? Because the consumer is what needs to know whether an error was thrown, you could
let employees; try { employees = await getEmployees(companyId); } catch(e) { /* handle */ }
– CertainPerformance
Jun 30 at 11:46