[英]Cannot figure Async/Await and Promises to work
我正在嘗試了解async
/ await
和Promise函數。 但是,經過大量的努力和研究,我找不到任何簡單的方法來獲得使用4 for循環的正確方法。
我給你代碼,如果Java語言不是異步的,應該如何處理。 您能告訴我在哪里(以及如何)承諾使我的代碼按預期工作?
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;
}
假設您使用貓鼬,則只需更換
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)
因為所有方法都已經返回了類似於promise的對象,所以您可以直接await
,而不是使用exec
並傳遞nodeback。
似乎您在這里嘗試做兩件事:您想異步地遍歷課程/課程/學生/技能,並進行相當耗時的Evaluation.findOne
調用。
我建議用async.forEach
替換部分或全部for循環。 您還可以將Evaluation.findOne
塊放入Promise
包裝的幫助器函數中,但是考慮到它在執行后被壓入lines
,因此這是一個可選步驟。
做這樣的事情:技能迭代現在使用async.forEach,並且行生成器有望實現。
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);
});
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.