Как использовать «async / await» и «обещания» для синхронного выполнения в Node.js? - PullRequest
0 голосов
/ 09 февраля 2019

Я довольно новичок в веб-разработке в целом, поэтому я не понимаю обещаний и асинхронных / ожидающих много.Я пытаюсь создать сайт публикации вакансии в качестве проекта, но застрял, потому что не могу заставить определенный фрагмент кода вести себя так, как мне хочется.

В следующем фрагменте рекрутер, который разместилконкретное требование работы хочет видеть навыки претендента, которые имеют отношение к требованию работы.Таким образом, код сначала получит данные о работе и заявителя, о которых идет речь, из коллекции mongodb.Затем он попытается сначала сохранить требуемые навыки кандидата, а затем все навыки кандидата в массиве навыков.Только после сохранения всех вышеперечисленных данных в навыках [] код должен отвечать последним json.Но он ведет себя не так, как я хочу, и отвечает до того, как сохранение завершено.Может кто-нибудь подсказать мне, как сделать его "синхронным"?

ПРИМЕЧАНИЕ. Я удалил всю обработку ошибок, чтобы сделать фрагмент кода короче.Кроме того, у заявителя есть 2 необходимых навыка из общего числа 5 навыков.

router.post('/recruiter/viewApplicant', passport.authenticate('jwt', {session: false}), (req, res, next) => {

    if(req.user.accountType === "Recruiter") {
        skills = [];

        Job.getJobByID((req.body.jobID),(err, job) => {
            User.getUserByEmail(req.body.email,(err, user) => {
                let i =0;
                job.requiredSkills.requirements.forEach(reqSkill => {
                    user.classData.forEach(classDetail => {
                        if(classDetail.classID === reqSkill.class.replace(/ /g, '-')) {
                            ClassData.getClassByclassID(classDetail.classID,(err, classInfo) => {
                                skills.push({
                                    type: 'req',
                                    imgURL: classInfo.imgURL,
                                    skill: classDetail
                                })
                                console.log('req: '+i)
                                i++
                            })
                        }
                    })
                })

                let k=0
                user.classData.forEach(classDetail => {
                    ClassData.getClassByclassID(classDetail.classID,(err, classInfo) => {
                        skills.push({
                            type: 'all',
                            imgURL: classInfo.imgURL,
                            skill: classDetail
                        })
                        console.log('all: '+k)
                        k++
                    })
                })
            }) 

            console.log("Completed");        
            res.json({success: true, msg: "Successful", data: skills});
        })
    }
});

Ожидаемый результат:

req: 0  
req: 1   
all: 0  
all: 1  
all: 2  
all: 3  
all: 4  
Completed  

Фактический результат:

Completed  
req: 0  
req: 1  
all: 0  
all: 1  
all: 2  
all: 3  
all: 4  

1 Ответ

0 голосов
/ 09 февраля 2019

Чтобы получить код, который вам нужен, переместите вызов res.json() следующим образом

            user.classData.forEach(classDetail => {
                ClassData.getClassByclassID(classDetail.classID,(err, classInfo) => {
                    skills.push({
                        type: 'all',
                        imgURL: classInfo.imgURL,
                        skill: classDetail
                    })
                    console.log('all: '+k);
                    k++;
                })
            })
            res.json({success: true, msg: "Successful", data: skills});

Он не работает там, где вы его положили, потому что ваш вызов .getJobById() немедленно возвращается.Когда он заканчивает работу, которую вы от него хотите, вы знаете, потому что он вызывает свою функцию обратного вызова.То же самое относится и к вложенному вызову .getUserByEmail().

async / await и Promise - способы организации обратных вызовов Javascript, чтобы они не выглядели вложенными.Они делают код проще для чтения.Но обратные вызовы все еще являются вложенными и асинхронными.Объяснение того, как именно преобразовать ваш код в использование Promises и async / await, выходит за рамки SO-ответа.Короче говоря, вы должны обещать свои асинхронные функции, тогда вы можете await их результаты .Абсолютно стоит потратить день или два на знакомство с этим способом кодирования в Javascript.

Совет Pro : если вы выполняете код такого типа с помощью отладчика, используйтеШаг во много.

...