Не могу понять Async / Await и Promises для работы - PullRequest
0 голосов
/ 02 мая 2018

Я пытаюсь узнать о async / await и функциях Promise. Однако, после долгих усилий и исследований, я не могу найти простой способ найти правильный способ использовать мои 4 для циклов.

Я даю вам код, каким он должен быть, если 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;
}

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Похоже, что вы пытаетесь сделать две вещи здесь: вы хотите асинхронно циклически проходить курсы / занятия / студенты / навыки и делать довольно длительный Evaluation.findOne вызов.

Я рекомендую заменить некоторые или все ваши циклы for на async.forEach. Вы также можете поместить блок 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);
        });
    });
}
0 голосов
/ 02 мая 2018

Если вы используете мангуста, все, что вам нужно изменить, это заменить

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 вместо использования exec и передачи нодбэка.

...