mongoose异步函数返回undefined

时间:2018-04-07 19:39:28

标签: node.js mongodb mongoose

我纠结于处理来自异步函数的返回数据,例如findOne(作为示例)等,我似乎无法做到正确。

在这段代码中,正在创建new_user,我想处理来自findOne函数的响应,但由于异步运行,用户为Null。我尝试了不同的方式,但我无法理解它。

var router = require('express').Router();
var mongoose = require('mongoose');
var user = require('../../Schemas/user');

router.get('/a', function (req, res, next) {
    var new_user = new user({
        "user_name": req.query.username, "first_name": req.query.firstname,
        "last_name": req.query.lastname,
        "email": req.query.email, "trips": []
    });

    user.findOne({ email: new_user.email }).exec(function (user) {
        if (!user) { return res.sendStatus(401); }
        else
            return res.send(user);
    });
});

module.exports = router;

我认为它是相同的,但我也尝试将查找代码放在另一个页面中并从router.get(' / a')中调用它,但结果却是相同的问题

API / user.js的:

new_user.checkUser(new_user.email).exec(function (user) {
    if (!user) {
        return res.sendStatus(401);
    }
    else
        return res.send(user);
})

用户架构:

var mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
    id: Number,
    user_name: String,
    first_name: String,
    last_name: String,
    email: { type: String, unique: true },
    trips: [{ id: { type: Number } }]
},
{ collection: 'users' });

userSchema.methods.checkUser = function (newUser) {
    return userM.findOne({ email: newUser }).exec(function (err, doc) {
        return doc; //doc contains the document for sure
    });
};

var userM = mongoose.model('user', userSchema);

module.exports = userM;

我知道这很简单,但在这一点上,它一切都很模糊。我将不胜感激。

1 个答案:

答案 0 :(得分:1)

.exec函数以(err, results)的形式返回,因此您应将其更改为:

user.findOne({ email: new_user.email }).exec(function (err, user) {
  if (err) {
    return next(err);
  }

  if (!user) {
    return res.sendStatus(401); 
  }

  res.send(user);
});

编辑: checkUser调用findOne这是一个异步函数,所以你应该使用async/await语法(1)或传递一个回调(2);

// 1
userSchema.statics.checkUser = function (newUser, cb) {
    return userM.findOne({ email: newUser }).exec(cb);
};

// 2
userSchema.statics.checkUser = async function (newUser) {
    return userM.findOne({ email: newUser });
};

所以你可以像下面一样消费它;

// 1
router.get('/a', function (req, res, next) {
    var new_user = new user({
        "user_name": req.query.username, "first_name": req.query.firstname,
        "last_name": req.query.lastname,
        "email": req.query.email, "trips": []
    });

    user.checkUser(new_user, function (err, user) {
        if (err) {
          return next(err)
        }

        if (!user) { return res.sendStatus(401); }
        else
            return res.send(user);
    });
});

// 2
router.get('/a', function (req, res, next) {
    var new_user = new user({
        "user_name": req.query.username, "first_name": req.query.firstname,
        "last_name": req.query.lastname,
        "email": req.query.email, "trips": []
    });

    try {
      const user = user.checkUser(new_user)
      if (!user) { return res.sendStatus(401); }
      else
          return res.send(user);
    } catch (err) {
      next(err)
    }
});