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

时间:2022-10-05 02:34:42

I have a basic mongoose authentication, with bcryptjs to hash passwords. Both bcrypt and mongoose return promises. In my routes.js I have the following script which gets stuck after finding the User in the db:

我有一个基本的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)
        );
});

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. In my user.js which defines my UserSchema I have this code to compare passwords:

正如您所看到的,我找到了用户,然后尝试调用其validate方法(被调用),但它不会解析promise也不会抛出错误。在我定义我的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. I guess I have to call then() immediately on the promise, but I don't see why.

如果我把比较方法放在routes.js中它可以工作,但这不是我想做的,我想把它保存在user.js中,但我想这可能会指出我仍然看不到的问题。我想我必须马上致电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)
        );

3 个解决方案

#1


0  

First of all why using Promise.all here? Especially i don't see the need for doing something like Promise.resolve(user). Without knowing how user.validate is working, i would write it like

首先为什么在这里使用Promise.all?特别是我不认为需要做像Promise.resolve(用户)这样的事情。不知道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))
});

#2


0  

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

#3


-1  

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

#1


0  

First of all why using Promise.all here? Especially i don't see the need for doing something like Promise.resolve(user). Without knowing how user.validate is working, i would write it like

首先为什么在这里使用Promise.all?特别是我不认为需要做像Promise.resolve(用户)这样的事情。不知道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))
});

#2


0  

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

#3


-1  

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