我的回调没有像预期的那样运行 node js
My callback doesn't behave as expected node js
我想做的是首先从学生集合中获取特定年级的所有学生和 class。然后使用那个要求的年级和 class 中的学生 ID,使用 mongoose
从 Marks 集合中找到使用这些学生 ID 的标记
这是我的学生架构
const StudentSchema = new Schema({
base_no:{
type: String,
required: true
},
grade: {
type: Number,
required: false
},
class: {
type: String,
required: false
}
});
const Student = module.exports = mongoose.model('student',StudentSchema,'student');
然后我在 Student 模型中使用这样的方法来获取特定年级和特定 class
的所有学生
/**
* Get all students of a class for a given grade
*
*/
module.exports.getStudentsGradeClass = function(params,callback){
Student.find({grade: params.grade, class: params.class},'base_no first_name last_name').sort({base_no: 1}).exec(callback);
}
这是我的标记架构
const MarksSchema = new Schema({
verifire: {
type: String,
required: true,
//index:true
},
student_base_id: { // as student auto gen key/index no
type: String,
required: true,
//index:true
},
subject_id: {
type: String,
required: true,
ref: 'subject',
//index:true
},
total: {
type: Number,
required: true
}
});
const Marks = module.exports = mongoose.model('school_marks', MarksSchema, 'school_marks');
所以我正在使用上面的 Student Schema 的 getStudentsGradeClass()
从客户端获取请求学生的方法
然后使用此代码
使用来自 getStudentsGradeClass() 方法的学生 ID 从 Marks 模式获取分数
/**
* Get marks of all students of the requested grade->class with subject_id
*
*/
module.exports.getClassResults = function (params, callback) {
let marks = [];
Student.getStudentsGradeClass({ grade: params.grade, class: params.class }, (err, students) => {
if (!err) {
for (let i = 0; i < students.length; i++) {
Marks.find({ subject_id: params.subject_id, student_base_id: students[i].base_no }, 'student_base_id total', (err, data) => {
if (!err) {
marks.push(data[0]);
} else {
callback(err, null);
}
});
}
callback(null,marks); // this is the function I wan to invoke
// right after the for loop finishes so
// that i can get all marks of all
//students for a specific subject..
// currently it is undefined(marks[]) coz it goes straight for the callback
// giving control to the for loop, the for loop gives data much later so that
// marks are not pushed to the array when I call it.
} else {
callback(err, null);
}
});
}
那么我可以这样做吗(我知道我在厄运金字塔中)。请给我一个更简洁的方法来做到这一点,或者你能指导我克服这个问题或者如何实现我想要达到的目标。非常感谢任何帮助。
你可以试试 async/await......
module.exports.getClassResults = (params, callback)=> {
let marks = [];
Student.getStudentsGradeClass({ grade: params.grade, class: params.class },async (err, students) => {
if (!err) {
for (let student of students){
let data=await Marks.find({ subject_id: params.subject_id, student_base_id: student.base_no }, 'student_base_id total')
if (data) {
marks.push(data[0]);
} else {
callback(err, null);
}
}
callback(null,marks); // this is the function I wan to invoke
// right after the for loop finishes so
// that i can get all marks of all
//students for a specific subject..
// currently it is undefined(marks[]) coz it goes straight for the callback
// giving control to the for loop, the for loop gives data much later so that
// marks are not pushed to the array when I call it.
} else {
callback(err, null);
}
});
}
我想做的是首先从学生集合中获取特定年级的所有学生和 class。然后使用那个要求的年级和 class 中的学生 ID,使用 mongoose
从 Marks 集合中找到使用这些学生 ID 的标记这是我的学生架构
const StudentSchema = new Schema({
base_no:{
type: String,
required: true
},
grade: {
type: Number,
required: false
},
class: {
type: String,
required: false
}
});
const Student = module.exports = mongoose.model('student',StudentSchema,'student');
然后我在 Student 模型中使用这样的方法来获取特定年级和特定 class
的所有学生/**
* Get all students of a class for a given grade
*
*/
module.exports.getStudentsGradeClass = function(params,callback){
Student.find({grade: params.grade, class: params.class},'base_no first_name last_name').sort({base_no: 1}).exec(callback);
}
这是我的标记架构
const MarksSchema = new Schema({
verifire: {
type: String,
required: true,
//index:true
},
student_base_id: { // as student auto gen key/index no
type: String,
required: true,
//index:true
},
subject_id: {
type: String,
required: true,
ref: 'subject',
//index:true
},
total: {
type: Number,
required: true
}
});
const Marks = module.exports = mongoose.model('school_marks', MarksSchema, 'school_marks');
所以我正在使用上面的 Student Schema 的 getStudentsGradeClass() 从客户端获取请求学生的方法 然后使用此代码
使用来自 getStudentsGradeClass() 方法的学生 ID 从 Marks 模式获取分数 /**
* Get marks of all students of the requested grade->class with subject_id
*
*/
module.exports.getClassResults = function (params, callback) {
let marks = [];
Student.getStudentsGradeClass({ grade: params.grade, class: params.class }, (err, students) => {
if (!err) {
for (let i = 0; i < students.length; i++) {
Marks.find({ subject_id: params.subject_id, student_base_id: students[i].base_no }, 'student_base_id total', (err, data) => {
if (!err) {
marks.push(data[0]);
} else {
callback(err, null);
}
});
}
callback(null,marks); // this is the function I wan to invoke
// right after the for loop finishes so
// that i can get all marks of all
//students for a specific subject..
// currently it is undefined(marks[]) coz it goes straight for the callback
// giving control to the for loop, the for loop gives data much later so that
// marks are not pushed to the array when I call it.
} else {
callback(err, null);
}
});
}
那么我可以这样做吗(我知道我在厄运金字塔中)。请给我一个更简洁的方法来做到这一点,或者你能指导我克服这个问题或者如何实现我想要达到的目标。非常感谢任何帮助。
你可以试试 async/await......
module.exports.getClassResults = (params, callback)=> {
let marks = [];
Student.getStudentsGradeClass({ grade: params.grade, class: params.class },async (err, students) => {
if (!err) {
for (let student of students){
let data=await Marks.find({ subject_id: params.subject_id, student_base_id: student.base_no }, 'student_base_id total')
if (data) {
marks.push(data[0]);
} else {
callback(err, null);
}
}
callback(null,marks); // this is the function I wan to invoke
// right after the for loop finishes so
// that i can get all marks of all
//students for a specific subject..
// currently it is undefined(marks[]) coz it goes straight for the callback
// giving control to the for loop, the for loop gives data much later so that
// marks are not pushed to the array when I call it.
} else {
callback(err, null);
}
});
}