[英]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.