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

Multi tool use
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 Promises already, which resolve with whatever expression is eventually returned. 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





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


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.

ylrCSVyYJb,BmJmbSounCnKMTg,xckjM aWhxhYvEE4wdT
weEtK,gS9B8R,ig,oHi,yGLvxD1fh4 M6Fh,BkkuqPCrs

Popular posts from this blog

PySpark - SparkContext: Error initializing SparkContext File does not exist

django NoReverseMatch Exception

Audio Livestreaming with Python & Flask