javascript - Node 中带有 Mongoose 和 Promise 的奇怪异步行为

标签 javascript node.js mongoose promise

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

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;
};

所以基本上它是一个身份验证路由,如果一切正常,它会发送一个签名的jwt奇怪的行为是,如果我发送错误的用户名,服务器会抛出一个错误

TypeError: Cannot read property 'validPassword' of null

所以,它说,当到达密码有效性检查时,user === null,但是,在此有效性检查之前,有一个检查,主要是找到用户

if (!user) reject({ success: false, reason: 'User not found or password is incorrect.' });

这里服务器已经知道user === null,因此它应该用success: false拒绝这个promise,并且这段代码应该被扔进catch 部分,但它没有发生。

请问有什么想法吗?

我应该补充一点,如果我将 if (!user.validPassword... 部分更改为 else if 而不是 if,它工作正常。但是我不明白为什么在 promise 被拒绝后仍然执行任何代码。

编辑

在学习node时,我主要使用了MEAN Machine book ,这是一个很大的帮助,他们使用这个语法:

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

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

最佳答案

您没有在 reject 上停止执行您的函数,所以如果 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 if :

 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);
   }
 });

关于javascript - Node 中带有 Mongoose 和 Promise 的奇怪异步行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33122726/

相关文章:

javascript - 在 index.html 之外访问 Cordova navigator.camera 插件未定义

javascript - 主干模型 - 根据 REST 操作更改 URL 查询参数

javascript - 如何处理 ETL 中无效的 Mongo/Mongoose ObjectId 分配

c# - REST api 不调用导航

javascript - Wordpress 子主题未通过 JQuery 应用样式

javascript - repl Node js问题SyntaxError : Unexpected identifier

c++ - 如何从插件中的单独 C++ 线程调用发射器回调?

javascript - Axios Post 登录请求显示待处理状态?

node.js - 在 Mongoose 中,如何仅删除集合中找到的一个文档?

mongodb - Mongoose.find() 如何查询属性大于某个数字或值为空或属性不存在的文档?