[英]How to ensure an asynchronous call is executed before returning from a function in Mongoose?
I am new to mongoose and in order to prevent ASYNC OF HELL I came Across an npm package called async .我是 mongoose 的新手,为了防止 ASYNC OF HELL,我遇到了一个名为async的 npm 包。 I have used the async.series
of the async npm package and my code looks in the given format given below我使用了async npm 包的async.series
并且我的代码看起来像下面给出的给定格式
var userId=1234
function findUser(callback){
user.findOne({userId:userId}).exec(function(err,userData){
//Some Logic
var schoolId=123;
var schoolName=findSchool(123);
findStudents(schoolName);
var schoolId=1234;
var schoolName=findSchool(123);
findStudents(schoolName);
callback(null);
});
}
function findSchool(schoolId){
school.findOne({schoolId:schoolId}).exec(function(err),schoolDetails){
//Some Logic
});
var schoolName="XYZ High School"
return(schoolName);
}
function findStudents(schoolName){
student.findOne({schoolName:schoolName}).exec(function(err),studentDetails{
//Some Logic
});
}
async.series([findUser],function(err){
// for Error Handling
}
Here I am using an async series function to prevent the ASYNC of HELL.这里我使用了一个 async series 函数来防止 HELL 的 ASYNC。 I am calling findUser
function in the async series call which is find the user details from my User
model using the userId
and then I am calling the findSchool
function inside the findUser
function which finds school details for the given SchoolId
in School
model.我打电话findUser
在异步调用系列是找到我的用户信息功能User
使用模型userId
,然后我打电话的findSchool
内部功能findUser
功能,发现对于给定的学校细节SchoolId
在School
模型。 Once the function returns the call I am trying to find the students based on a particular schoolName
using the findStudents
function on the Student
model.一旦函数返回调用,我将尝试使用Student
模型上的findStudents
函数根据特定schoolName
findStudents
Student
。
The process is repeated for a different schoolId
.对不同的schoolId
重复该过程。 My Issue comes when I call the findSchool
function.当我调用findSchool
函数时,我的问题就出现了。 Since it has a asynchronous call ( findOne
) on the school
model, I am able to return the value of the schoolName
even before the findOne
is completed for the model.由于它在school
模型上有一个异步调用 ( findOne
),因此即使在模型的findOne
完成之前,我也能够返回schoolName
的值。
Is there a way to ensure that the given function findSchool
doesn't return the value of the schoolName
until the school.findOne()
has completed successfully?有没有一种方法,以确保给定函数findSchool
不返回的值schoolName
直到school.findOne()
已成功完成? Just to add more clarity I don't want to my return statement inside the findOne
of the findSchool
function.我想补充更清晰,我不希望里面我return语句findOne
的的findSchool
功能。
Async.each or async.waterfall should do the trick, I think.我认为 Async.each 或 async.waterfall 应该可以解决问题。
The main thing here is that you're using return statements in your async functions, which will return before the async function has actually completed, and thus they won't pass along what you need.这里的主要问题是您在异步函数中使用 return 语句,它将在异步函数实际完成之前返回,因此它们不会传递您需要的内容。
You have to use async functions and callbacks for this.您必须为此使用异步函数和回调。 You can still have your functions separated like you want in your code, but you'll have to add callback functions instead of returns.您仍然可以像在代码中一样将函数分开,但是您必须添加回调函数而不是返回函数。
You should still use async
but you need async.waterfall
for that.你仍然应该使用async
但你需要async.waterfall
。 Here is what you need to consider:以下是您需要考虑的事项:
A main method to call your async
function:调用async
函数的主要方法:
var getInformation = function(){
async.waterfall([
//Array of your functions in order, we will be back here later
], function (err) {
if(err){
console.log(err);
}else{
console.log('Everything OK!');
}
);
}
Then you need your functions to be async
friendly, that means you should use callbacks and give your data from one function to another.然后你需要你的函数async
友好,这意味着你应该使用回调并将数据从一个函数传递给另一个函数。 Something like this:像这样的东西:
function findUser(callback){
//Do something
if('Everything OK'){
callback(err, yourData); //err should be null if everything is OK and yourData should be the data that you wanna use in your next function. e.g. schoolId
}else{
callback(err); //Something was wrong, "err" should have something different to null
}
}
function findSchool(callback, schoolId){ //Note that we receive the parameter schoolId here but not in the first function
//Do something
if('Everything OK'){
callback(err, yourData); //err should be null if everything is OK and yourData should be the data that you wanna use in your next function. e.g. schoolName
}else{
callback(err); //Something was wrong, "err" should have something different to null
}
}
function findStudents(callback, schoolName){
//Do something
if('Everything OK'){
callback(err); //err should be null if everything is OK if this is the last function maybe we don't need to send back more data from here
}else{
callback(err); //Something was wrong, "err" should have something different to null
}
}
Then you should call your functions in your main method:然后你应该在你的 main 方法中调用你的函数:
var getInformation = function(){
async.waterfall([
findUser,
findSchool,
findStudents
//Note that there is no need to tell the functions the parameters they are sending or receiving here
], function (err) {
if(err){
console.log(err);
}else{
console.log('Everything OK!');
}
);
}
And that's it, you have 3 functions that should be executed one after the other and no callback hell is needed.就是这样,你有 3 个函数应该一个接一个执行,不需要回调地狱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.