如何调用函数返回对promise的结果的承诺?

时间:2017-01-02 10:47:25

标签: javascript node.js mongoose es6-promise

我有一个基本的mongoose身份验证,使用bcryptjs来哈希密码。 bcrypt和mongoose都回报了承诺。在我的routes.js中,我有以下脚本在db中找到User后被卡住了:

routes.post('/auth', (req, res)=> {
    User.findOne({'local.username': req.body.username})
        .then(
            user=> Promise.all([user, user.validate(req.body.password)])
        )
        .then(
            results => {
                console.log(results);
                res.json({token: jwt.sign({id: results[0]._id}, config.secret)});
            }
        )
        .catch(
            err=> console.log(err)
        );
});

正如你所看到的,我找到了用户,然后尝试调用它的validate方法(被调用),但它不会解决这个问题,也不会抛出错误。在我定义我的UserSchema的user.js中,我有这个代码来比较密码:

UserSchema.methods.validate = function (password) {
    return bcrypt.compare(password, this.local.password);
};

这是被调用的,但是返回的promise似乎消失了,它没有被解析,结果变量永远不会被记录。

如果我编辑用户验证代码,还有一件事:

UserSchema.methods.validate = function (password) {
    return bcrypt.compare(password, this.local.password).then(
        results => {
            console.log(results)
        }
    )
};

我真的登录到控制台,所以它必须正常工作,但我不想在这里解决我的承诺,我想在我的路由器中附加.then(...),不是吗?有可能吗?

我做错了什么?

更新

如果我将比较方法放在routes.js中它可以工作,但这不是我想做的,我想把它保存在user.js中,但我想这可能会指出我仍然存在的问题看不到。我想我必须马上打电话给那个承诺,但我不明白为什么。

 User.findOne({'local.username': req.body.username})
        .then(
            user=> Promise.all([user, bcrypt.compare(req.body.password,user.local.password)])
        )
        .then(
            results => {
                console.log(results);
                res.json({token: jwt.sign({id: results[0]._id}, config.secret)});
            }
        )
        .catch(
            err=> console.log(err)
        );

3 个答案:

答案 0 :(得分:0)

首先为什么在这里使用Promise.all?特别是我认为不需要做Promise.resolve(user)这样的事情。在不知道user.validate如何工作的情况下,我会像

一样写出来
routes.post('/auth', (req, res)=> {
    let userId

    User.findOne({'local.username': req.body.username})
    .then(user => {
      userId = user._id
      return user.validate(req.body.password)
    })
    .then(results => {
      console.log(results);
      res.json({token: jwt.sign({id: userId}, config.secret)});
    })
    .catch(err => console.log(err))
});

答案 1 :(得分:0)

我发现,问题在于猫鼬。它包装模块方法,并承诺在某处“迷路”。解决方案是使用同步比较方法,或提供回调。

另外我在github上创建了这个问题: https://github.com/Automattic/mongoose/issues/4856

答案 2 :(得分:-1)

你没有对Promise做任何事。你在当时打电话。

而不是

user=> Promise.all([user, user.validate(req.body.password)])

你应该这样:

user.validate(req.body.password)
.then(results => {
    // Do stuff with results here...
});