我是mongoose的新手,为了防止ASYNC OF HELL,我来到了一个名为async的npm包中。我使用了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
}
这里我使用异步系列函数来阻止HELL的ASYNC。我在异步系列调用中调用findUser
函数,该函数使用User
从我的userId
模型中查找用户详细信息,然后调用findSchool
函数在 findUser
函数中找到SchoolId
模型中给定School
的学校详细信息。函数返回通话后,我尝试使用schoolName
模型上的findStudents
函数根据特定Student
找到学生。
对不同的schoolId
重复该过程。当我调用findSchool
函数时,我的问题出现了。由于它在findOne
模型上有异步调用(school
),因此即使在模型完成schoolName
之前,我也能够返回findOne
的值。
有没有办法确保给定的函数findSchool
在schoolName
成功完成之前不会返回school.findOne()
的值?只是为了增加更清晰度,我不希望到我的返回语句里面 findOne
函数的findSchool
。
答案 0 :(得分:0)
Async.each或async.waterfall应该可以解决这个问题。
这里最重要的是你在异步函数中使用return语句,它将在异步函数实际完成之前返回,因此它们不会传递你需要的东西。
您必须为此使用异步函数和回调。您仍然可以在代码中将功能分开,但是您必须添加回调函数而不是返回。
答案 1 :(得分:0)
您仍然应该使用async
,但您需要async.waterfall
。以下是您需要考虑的事项:
调用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!');
}
);
}
然后你需要你的函数async
友好,这意味着你应该使用回调并将你的数据从一个函数提供给另一个函数。像这样:
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
}
}
然后你应该用你的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!');
}
);
}
就是这样,你有三个应该一个接一个地执行的功能,并且不需要回调地狱。