Javascript Mongoose和promises节点中奇怪的异步行为

Javascript Mongoose和promises节点中奇怪的异步行为,javascript,node.js,mongoose,promise,Javascript,Node.js,Mongoose,Promise,所以我使用Node.js+Mongoose+Lie作为承诺库。代码如下: var User = require('../models/user'), Promise = require('lie'), jwt = require('jsonwebtoken'), config = require('../../config'); module.exports = function(express) { var router = express.Router();

所以我使用Node.js+Mongoose+Lie作为承诺库。代码如下:

var User = require('../models/user'),
    Promise = require('lie'),
    jwt = require('jsonwebtoken'),
    config = require('../../config');

module.exports = function(express) {
    var router = express.Router();

    router.post('/', function(req, res) {
        if (!req.body.username) return res.json({ success: false, reason: 'Username not supplied.' });
        if (!req.body.password) return res.json({ success: false, reason: 'Password not supplied.' });

        var findUser = new Promise(function(resolve, reject) {
            User.findOne({ username: req.body.username }, function(err, user) {
                if (err) reject (err);
                if (!user) reject({ success: false, reason: 'User not found or password is incorrect.' });
                if (!user.validPassword(req.body.password)) reject({ success: false, reason: 'User not found or password is incorrect.' });
                resolve(user);
            });
        });

        var sendToken = function(user) {
            var token = jwt.sign({ username: user.username }, config.secret, { expiresIn: 2 * 60 * 60 });
            res.json({ success: true, token: token });
        };

        findUser.then(function(value) {
            sendToken(value);
        }).catch(function(reason) {
            res.send(reason);
        });

    return router;
};
所以基本上它是一个auth路由,如果一切正常,它会发送一个签名的
jwt
。奇怪的是,如果我发送了一个错误的用户名,服务器就会抛出一个错误

TypeError: Cannot read property 'validPassword' of null
因此,当它到达密码有效性检查时,它表示
用户===null
,然而,在这个有效性检查之前,有一个检查,主要是找到了一个用户

if (!user) reject({ success: false, reason: 'User not found or password is incorrect.' });
在这里,服务器已经知道
user===null
,因此它应该以
success:false
拒绝这个承诺,并且这段代码应该被扔进
catch
部分,但它没有发生

有什么想法吗

我应该补充一点,如果我将
if(!user.validPassword…
部分改为
else if
,而不是
if
,它会像它应该的那样工作。但是我无法理解为什么承诺被拒绝后仍然执行任何代码

编辑 在学习节点时,我主要使用了,这是一个很大的帮助,在那里他们使用以下语法:

if (!user) {
    //
} else if (user) {
    //
}

但是我想它也应该按我的方式工作。

您并没有停止在
拒绝
上执行函数,因此如果
findOne
导致空结果
validPassword
仍会被调用

您可能需要添加
return

 User.findOne({ username: req.body.username }, function(err, user) {
   if (err)
     return reject (err);
   if (!user)
     return reject({ success: false, reason: 'User not found or password is incorrect.' });
   if (!user.validPassword(req.body.password))
     return reject({ success: false, reason: 'User not found or password is incorrect.' });
   resolve(user);
 });
或者在以下情况下使用
else:

 User.findOne({ username: req.body.username }, function(err, user) {
   if (err) { 
     reject (err);
   } else if (!user) {
     reject({ success: false, reason: 'User not found or password is incorrect.' });
   } else if (!user.validPassword(req.body.password))
     reject({ success: false, reason: 'User not found or password is incorrect.' });
   } else {
     resolve(user);
   }
 });

这是有道理的。我想我只是认为这意味着
resolve
reject
应该停止执行:D谢谢!