函数给未定义

时间:2019-12-23 18:55:16

标签: javascript node.js mongodb class callback

我正在使用nodejs进行登录过程,我想在模块外部定义一个全局函数,然后在模块中多次调用它,但是它总是返回undefined,而当我console.log进入它时,我发现有数据。 首先,这是我使用的Facebook登录策略的示例:

  class Auth {  
      FacebookStrategy(req, res) {
                passport.use('facebook', new Facebook({
                    clientID: process.env.FACEBOOK_CLIENT_ID,
                    clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
                    callbackURL: `http://${process.env.DOMAINE}/auth/facebook/callback`,
                    profileFields: ["email", "name", "photos", "displayName"],
                    passReqToCallback: true
                }, (req, accessToken, refreshToken, profile, done) => {
                    let db = req.app.db;
                    db.collection("utilisateur").findOne({ "email": profile.emails[0].value, "isdelete": { $exists: false } },
                        async function (err, user) {
                            if (err) done({ "mongo err ": err })
                            if (user) {
                                let newJWT = await generateJWT(user);
                                 let tokenUpdate = await updateDBJWT(req.app.db, user._id, newJWT);
                                // return db.collection("utilisateur").findOneAndUpdate({ "_id": user._id }, { $set: { "token": newJWT } },
                                //     { returnOriginal: false }, (err, user) => {
                                //         if (err) return (err)
                                //         done(null, user.value);
                                //     });
                                done(user,tokenUpdate);
                            } else {
                                let newUser = {};
                                newUser.name = profile.displayName;
                                newUser.email = profile.emails[0].value;
                                newUser.role = 'client';
                                newUser.image = profile.photos[0].value;
                                newUser.dateInsert = moment().utc(1).format("YYYY-MM-DD HH:mm:ss");
                                newUser.connextionProvider = {
                                    "provider_id": profile.id,
                                    "provider": 'facebook'
                                };
                                let token = generateJWT(newUser);
                                newUser.token = token;
                                db.collection("utilisateur").insertOne(newUser, async function (err, insertedUser) {
                                    if (err) done(err);
                                    let data = insertedUser.ops[0];
                                    done(null, data);
                                });
                            }
                        });
                })
                );
            }
}
module.exports = Auth;

我的问题是这个字段tokenUpload,它总是返回undefined

let tokenUpdate = await updateDBJWT(req.app.db, user._id, newJWT);

这是与auth类在同一页面中但在模块外部的updateDBJWT

function updateDBJWT(db, userId, token) {
    return db.collection("utilisateur").findOneAndUpdate({ "_id": userId }, { $set: { "token": token } }, { returnOriginal: false }, (err, user) => {
        if (err) return (err)
        console.log('user value ', user.value);
        return (user.value);
    });
}

每次我用该函数替换tokenUpload行时,它都不会出现问题,但是当我调用它时,却什么也没有,如果有任何帮助,我将不胜感激,谢谢

1 个答案:

答案 0 :(得分:1)

  

由于“ findOneAndUpdate()函数”的异步行为,   findAndUpdate需要时间来执行更新查询,而解释器则不需要   等待结果并在响应中返回undefined。

我知道您正在使用async / await,但无法按要求的方式工作。

  

所以您可以做的是将updateDBJWT()函数包装到一个promise中   功能,并在结果到达时解决,否则拒绝。

     

然后将整个代码包装到一个then函数中   调用updateDBJWT()函数。

我已经在下面进行了更改,您只需要复制粘贴并检查其是否有效

执行以下操作:-

function updateDBJWT(db, userId, token) {
return new Promise(function(resolve,reject){
    db.collection("utilisateur").findOneAndUpdate({ "_id": userId }, { $set: { "token": token } }, { returnOriginal: false }, (err, user) => {
        if (err) reject (err)
     else{
        console.log('user value ', user.value);
        resolve (user.value);
     }

    });
})

}

在您的主要代码中:-

   class Auth {  
      FacebookStrategy(req, res) {
                passport.use('facebook', new Facebook({
                    clientID: process.env.FACEBOOK_CLIENT_ID,
                    clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
                    callbackURL: `http://${process.env.DOMAINE}/auth/facebook/callback`,
                    profileFields: ["email", "name", "photos", "displayName"],
                    passReqToCallback: true
                }, (req, accessToken, refreshToken, profile, done) => {
                    let db = req.app.db;
                    db.collection("utilisateur").findOne({ "email": profile.emails[0].value, "isdelete": { $exists: false } },
                        async function (err, user) {
                            if (err) done({ "mongo err ": err })
                            if (user) {
                                let newJWT = await generateJWT(user);
                                  updateDBJWT(req.app.db, user._id, newJWT).then(function(tokenUpdate){
                                    done(user,tokenUpdate);
                                  }).catch(function(err){
                                      console.error(err);
                                  })
                                // return db.collection("utilisateur").findOneAndUpdate({ "_id": user._id }, { $set: { "token": newJWT } },
                                //     { returnOriginal: false }, (err, user) => {
                                //         if (err) return (err)
                                //         done(null, user.value);
                                //     });

                            } else {
                                let newUser = {};
                                newUser.name = profile.displayName;
                                newUser.email = profile.emails[0].value;
                                newUser.role = 'client';
                                newUser.image = profile.photos[0].value;
                                newUser.dateInsert = moment().utc(1).format("YYYY-MM-DD HH:mm:ss");
                                newUser.connextionProvider = {
                                    "provider_id": profile.id,
                                    "provider": 'facebook'
                                };
                                let token = generateJWT(newUser);
                                newUser.token = token;
                                db.collection("utilisateur").insertOne(newUser, async function (err, insertedUser) {
                                    if (err) done(err);
                                    let data = insertedUser.ops[0];
                                    done(null, data);
                                });
                            }
                        });
                })
                );
            }
}
module.exports = Auth;

如果您仍然不确定,请告诉我。

希望这会有所帮助!