我试图了解async
/ await
和Promise函数。然而经过大量的努力和研究,我找不到任何简单的方法来使用我的4 for循环。
如果Javascript不是异步的话,我会告诉你代码应该如何。你能告诉我在哪里(以及如何)我可以通过承诺让我的代码按预期工作吗?
function (courses) {
var lines = [];
for (var i = 0; i < courses.length; i++) {
var course = courses[i];
var sessions = course.sessions;
var students = course.students;
var skills = course.skills;
console.log('\nCourse : ' + course);
for (var j = 0; j < sessions.length; j++) {
var session = sessions[j];
console.log('\nSession : ' + session);
for (var k = 0; k < students.length; k++) {
var student = students[k];
console.log('\nStudent : ' + student);
for (var l = 0; l < skills.length; l++) {
var skill = skills[l];
console.log('\nSkill : ' + skill);
Evaluation.findOne({
student_id: student._id,
session_id: session._id,
skill_id: skill._id
}).exec(function (err, eval) {
console.log('\nStudentID : ' + eval);
console.log('\nSessionID : ' + eval);
console.log('\nSkillID : ' + eval);
console.log('\nEval : ' + eval);
var line = [];
line.push(course.name);
line.push(session.date);
line.push(student.firstname);
line.push(student.name);
if (eval) {
line.push(eval.name);
line.push(eval.mark);
}
else {
line.push(skill.name);
line.push('Not Evaluated');
}
lines.push(line)
})
}
}
}
}
return lines;
}
答案 0 :(得分:1)
假设您使用mongoose,您需要更改的只是替换
client.time_series("https://api.fitbit.com/1/user/-/activities/heart/date/today/1d.json", period="1d")
通过
Evaluation.findOne({
student_id: student._id,
session_id: session._id,
skill_id: skill._id
}).exec(function (err, eval) {
console.log('\nStudentID : ' + eval);
console.log('\nSessionID : ' + eval);
console.log('\nSkillID : ' + eval);
console.log('\nEval : ' + eval);
var line = [];
line.push(course.name);
line.push(session.date);
line.push(student.firstname);
line.push(student.name);
if (eval) {
line.push(eval.name);
line.push(eval.mark);
} else {
line.push(skill.name);
line.push('Not Evaluated');
}
lines.push(line)
})
因为所有方法都已经返回类似承诺的对象,您可以直接const eval = await Evaluation.findOne({
// ^^^^^
student_id: student._id,
session_id: session._id,
skill_id: skill._id
});
console.log('\nStudentID : ' + eval);
console.log('\nSessionID : ' + eval);
console.log('\nSkillID : ' + eval);
console.log('\nEval : ' + eval);
var line = [];
line.push(course.name);
line.push(session.date);
line.push(student.firstname);
line.push(student.name);
if (eval) {
line.push(eval.name);
line.push(eval.mark);
} else {
line.push(skill.name);
line.push('Not Evaluated');
}
lines.push(line)
,而不是使用await
并传递节点回传。
答案 1 :(得分:0)
看起来你在这里尝试做两件事:你想要异步循环课程/课程/学生/技能,并进行相当耗时的Evaluation.findOne
电话。
我建议使用async.forEach
替换部分或全部for循环。您还可以将Evaluation.findOne
块放入包含在Promise
中的辅助函数中,但考虑到它在执行后被lines
推送到function (courses) {
var lines = [];
for (var i = 0; i < courses.length; i++) {
var course = courses[i];
var sessions = course.sessions;
var students = course.students;
var skills = course.skills;
console.log('\nCourse : ' + course);
for (var j = 0; j < sessions.length; j++) {
var session = sessions[j];
console.log('\nSession : ' + session);
for (var k = 0; k < students.length; k++) {
var student = students[k];
console.log('\nStudent : ' + student);
skills.forEach(function(skill) {
console.log('\nSkill : ' + skill);
buildStudentLine(student, session, skill, course)
.then((line )=> {
lines.push(line);
})
.catch((error) => {
console.log(error);
})
});
}
}
}
return lines;
}
function buildStudentLine(student, session, skill, course) {
return new Promise((resolve, reject) => {
Evaluation
.findOne({
student_id: student._id,
session_id: session._id,
skill_id: skill._id
})
.exec(function (err, evaluated) {
var line = [];
line.push(course.name);
line.push(session.date);
line.push(student.firstname);
line.push(student.name);
if (evaluated) {
line.push(evaluated.name);
line.push(evaluated.mark);
} else {
line.push(skill.name);
line.push('Not Evaluated');
// possibly put this in here if you don't want the line to enter the lines array:
// reject('Not Evaluated');
}
resolve(line);
});
});
}
。是一个可选的举动。
执行以下操作:技能迭代现在使用async.forEach,而行构建器就在承诺中。
foo AND bar