如何在 Node.js 中使用 "async/await" 和 "promises" 进行同步执行?



作为一个整体,我对web开发相当陌生,所以我对promise和async/await不太了解。我正试图将一个招聘网站作为一个项目来构建,但由于无法使特定的代码按照我的意愿运行,我陷入了困境。

在下面的片段中,发布特定工作要求的招聘人员希望了解申请人与工作要求相关的技能。因此,代码将首先从mongodb集合中获取工作详细信息和有问题的申请人的详细信息。然后,它将尝试首先存储申请人所需的技能,然后将申请人的所有技能存储在技能数组中。只有在skill[]中存储了以上所有数据之后,代码才应该使用最后一个json进行响应。但它的行为并不像我想要的那样,它在存储完成之前就做出了响应。有人能指导我如何使它"同步"吗?

注意:我删除了所有的错误处理,以缩短代码段。此外,申请人具备5项技能中的2项所需技能。

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  

要获得必须工作的代码,请按以下移动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中的这种编码方式是绝对值得的。

专业提示:如果您使用调试器逐步完成此类代码,请大量使用step Into。

最新更新