如何在nodejs中使函数调用等待

问题描述

        async function login (req,res,next)  {
        return new Promise(function (resolve,reject) {
        var username = req.body.userName;
        var password = req.body.password;
        var otp = req.body.otp;
        var event = req.body.event;
        var Id = req.body.ObjId;
        var role = req.body.role;
        let data1 = {};
        usermodel.findOne({ username: username,status: "Active" }).then(data => {
            if (data && pwdhash.verify(password,data['password'])) {
             UserTokenModel.findOne({ UserId: data._id,Status: "Active",Accesstoken: otp }).then(usertokenDoc => {
                    var currentTime = new Date();
                    var tokenCreationTime = usertokenDoc.Date.toUTCString();
                    var tokenCreationTimeUtc = new Date(tokenCreationTime + UTC");
                    var difference = currentTime - tokenCreationTimeUtc;
                    if (difference < 0) {
                        difference = 0;
                    }
                    var diffMinutes = Math.floor((difference / 1000) / 60);
                    if (diffMinutes > 3) {
         res.sendResponse(500,false,null,"OTP   timeout,regeneratethe OTP.");
                    } else {
                        let token = jwt.sign({ username: data['username'],user_id: data['_id'] },config.secret,{ expiresIn: config.tokenExpiry });
                        data1.email = data.email;
                        data1.token = token;
                        data1.username = data.username;
                        data1.status = data.status;
                        data1.role = data.role;
                        data1.application = data.application;
                        var ObjId =   saveUserAccessDetails(req,role,username,event,Id);
                        resolve('Authentication Successful...' + ObjId);
                        res.sendResponse(200,true,data1,'Authentication  Successful...'+ObjId);
                    }
                }).catch(err => {
                    reject("OTP hasn't generated for this user.");
                    res.sendResponse(500,"OTP hasn't generated for this user.");
                })
            } else {
                reject('Incorrect Username or password');
                res.sendResponse(403,'Incorrect Username or     password');
            }
        }).catch(err => {
            reject(err);
            res.sendResponse(500,err.toString());
        })
      })
     
    function saveUserAccessDetails(req,name,Id) {
    return new Promise(function (resolve,reject) {        
       var channel = req.body.channel;
        var networkDetailsObj = req.body.networkDetails;
       
        var userAccessModel = new UserAccessLogModel({
            "user_name": name,"networkDetails": networkDetailsObj,"loggedIn_systemIp": req.body.loggedInSystemIp,"channel": req.body.channel,"loginTime": req.body.loginTime,"logoutTime": req.body.logoutTime,"name": name,"role": role,"Event_name": event
        });

        if (event == "logout") {
            userAccessModel.findOneAndUpdate({
                _id: Id
            },{
                $addToSet: {
                    logoutTime: logoutTime
                }
            },{
                new: true
            },function (err,accessDoc) {
                if (err) {
                    reject(err);
                } else {
                    resolve(accessDoc._id);
                }
            })
        } else {
            userAccessModel.save( function (err,logDoc) {
                if (err) {
                    console.log("error While saving access log" + err);
                    reject(err);
                } else {
                    console.log("Access log saved successfully..." + logDoc._id);
                    resolve(logDoc._id);
                }
            })
        }
    })
}

我想发送 saveUserAccessDetails 函数的返回值作为登录 api 的响应,但它返回 undefined 因为它在 saveUserAccessDetails 函数返回值之前执行,实际上 fuctinality 正在异步执行,但是我只是让它同步但它不工作预期的 。请指导更改。

解决方法

您需要像这样将 saveUserAccessDetails 转换为异步函数:

 async function saveUserAccessDetails(req,role,name,event,Id) {
 }

在函数内部执行所有逻辑并从 MongoDB 数据库返回数据。

在登录功能里面,改成:

async function login (req,res,next)  {
 ...
 var ObjId = await saveUserAccessDetails(req,username,Id);
 ...
}