简体   繁体   English

如何调用一个根据诺言的结果返回诺言的函数?

[英]How to call a function returning a promise on a result of a promise?

I have a basic mongoose authentication, with bcryptjs to hash passwords. 我有一个基本的猫鼬身​​份验证,使用bcryptjs哈希密码。 Both bcrypt and mongoose return promises. bcrypt和猫鼬都返回承诺。 In my routes.js I have the following script which gets stuck after finding the User in the db: 在我的routes.js中,我有以下脚本,该脚本在数据库中找到用户后卡住了:

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

As you can see I find the user, and then try to call its validate method (which gets called), but it won't resolve the promise nor throw an error. 如您所见,我找到了用户,然后尝试调用其validate方法(将被调用),但它不会解决诺言,也不会引发错误。 In my user.js which defines my UserSchema I have this code to compare passwords: 在定义UserSchema的user.js中,我具有以下代码来比较密码:

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

This is called, but the returned promise seems like it vanishes, it is not resolved, the results variable is never logged. 这被称为,但是返回的promise似乎消失了,它没有被解析,并且从不记录结果变量。

One more thing, if I edit user validation code to this: 还有一件事,如果我将用户验证代码编辑为此:

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

I get true logged to console, so it must be working but I don't want to resolve my promise here, I want to attach the .then(...) in my router, isn't it possible? 我确实登录到控制台,所以它一定可以正常工作,但是我不想在这里解决我的诺言,我想在路由器中附加.then(...),这是不可能的吗?

What am I doing wrong? 我究竟做错了什么?

UPDATE: 更新:

If I put the compare method in the routes.js it works, but that is not what I want to do, I want to keep it in the user.js, but I thought this might point out the problem which I still cannot see. 如果将compare方法放到route.js中,它可以工作,但是那不是我想要的,我想将其保留在user.js中,但是我认为这可能指出了我仍然看不到的问题。 I guess I have to call then() immediately on the promise, but I don't see why. 我想我必须立即在promise上调用then(),但是我不明白为什么。

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

First of all why using Promise.all here? 首先,为什么在这里使用Promise.all? Especially i don't see the need for doing something like Promise.resolve(user) . 特别是我不认为需要做类似Promise.resolve(user)事情。 Without knowing how user.validate is working, i would write it like 不知道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))
});

I found out, that the problem is with mongoose. 我发现问题出在猫鼬身上。 It wraps the module methods, and promises "get lost" somewhere. 它包装了模块方法,并承诺在某处“迷路”。 The solution to this is to use a sync compare method, or provide a callback. 解决方案是使用同步比较方法或提供回调。

Also I created an issue with this on github: https://github.com/Automattic/mongoose/issues/4856 我也在github上创建了一个问题: https : //github.com/Automattic/mongoose/issues/4856

You are not doing anything with the Promise.all you call in the then. 您对Promise并没有做任何事情。

Instead of 代替

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

You should then it: 然后,您应该:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM