[英]Node.js Mongoose Promise getting lost
I have a Node.js API with a mongoDB. 我有一个mongoDB的Node.js API。 There is a route that creates a user and needs to hash the password, for this I use the bcryptjs package.
有一种方法可以创建用户,并且需要对密码进行哈希处理,为此,我使用了bcryptjs包。
the route looks like this: 路线如下所示:
router.route('/user')
.post(function(req, res) {
if(req.body.password === req.body.passwordConfirm) {
userManager.addUser(req.body)
.then(function(response) { // waiting for the result of the mongoDB save
res.send({data:response});
});
} else {
res.send({err:'passwords do not match'});
}
})
and userManager.addUSer: 和userManager.addUSer:
this.addUser = function(userobject) {
bcrypt.genSalt(10, function(err, salt) { // generate a salt
if(err !== null) {
console.log(err);
} else {
bcrypt.hash(userobject.password_hash, salt, function(err, hash) { // hash pw
if(err !== null) {
console.log(err);
else {
userobject.password_hash = hash; // store hash in user obj
var user = new User(userobject);
return user.save().catch(function(err){ // save user in mongoDB
console.log(err);
});
}
});
}
});
};
I get an error saying: "Cannot read property 'then' of undefined", which tells me that I am not receiving a promise from addUser. 我收到一条错误消息:“无法读取未定义的属性'then'”,这告诉我我没有收到addUser的承诺。 I looked and bcryptjs sadly does not use promises, however, mongoose does.
我看了一下,可悲的是bcryptjs不使用promises,但是猫鼬却使用了promises。 (adding this:
(添加以下内容:
var mongoose = require('mongoose').Promise = Promise;
didn't help) 没有帮助)
I tried wrapping the function in a promise with reject and resolve, but that gives this error: "TypeError: Promise resolver undefined is not a function". 我尝试将函数包装在带有拒绝和解决的Promise中,但是会出现此错误:“ TypeError:Promise解析器未定义不是函数”。
How do I get the promise that the save() function of mongoose returns back to the .then() in the post route? 我如何保证猫鼬的save()函数在发布路线中返回到.then()? I tried adding return in front of the two bcrypt function but that didn't work either..
我尝试在两个bcrypt函数的前面添加return,但这也不起作用。
Any suggestions are welcome! 欢迎任何建议!
Your addUser
function nevers returns the promise to its caller. 您的
addUser
函数永远不会将诺言返回给其调用者。 You're doing a return
from the bcrypt.hash
callback function, but that has nothing to do with addUser
's return value. 您正在从
bcrypt.hash
回调函数return
,但这与addUser
的返回值无关。
It looks like addUser
has to use some non-Promise-enabled APIs, so you're stuck with doing new Promise
, something like this (see the ***
comments): 看来
addUser
必须使用一些未启用Promise的API,因此您不得不执行new Promise
,类似这样(请参见***
注释):
this.addUser = function(userobject) {
return new Promise(function(resolve, reject) { // ***
bcrypt.genSalt(10, function(err, salt) { // generate a salt
if(err !== null) {
reject(err); // ***
} else {
bcrypt.hash(userobject.password_hash, salt, function(err, hash) { // hash pw
if(err !== null) {
reject(err); // ***
else {
userobject.password_hash = hash; // store hash in user obj
var user = new User(userobject);
resolve(user.save()); // *** save user in mongoDB
}
});
}
});
});
};
Also note that I don't have addUser
just swallowing errors; 另请注意,我没有
addUser
只是吞下了错误; instead, they're propagated to the caller. 相反,它们会传播给调用方。 The caller should handle them (even if "handling" is just logging).
调用者应处理它们(即使“处理”只是记录)。
You do not return a Promise form your this.addUser
, you have to convert your callback based bcrypt
to Promises. 您无需从
this.addUser
返回Promise,而必须将基于回调的bcrypt
转换为Promises。 You can convert the whole bcrypt
API to support Promise based functions using eg promisifyAll
of the bluebird library, or do it manually using new Promise
like this way: 您可以使用例如bluebird库的
promisifyAll
将整个bcrypt
API转换为支持基于Promise的功能,或者使用new Promise
手动执行此操作,如下所示:
this.addUser = function(userobject) {
return new Promise((resolve, reject) => {
bcrypt.genSalt(10, (err, salt) => {
if (err) {
reject(err);
} else {
bcrypt.hash(userobject.password_hash, salt, function(err, hash) {
if (err) {
reject(err)
} else {
resolve(hash)
}
})
}
});
})
.then(hash => {
userobject.password_hash = hash; // store hash in user obj
var user = new User(userobject);
return user.save() // save user in mongoDB
})
.catch(function(err) {
console.log(err);
});
}
Or that way: 或那样:
this.addUser = function(userobject) {
return new Promise((resolve, reject) => {
bcrypt.genSalt(10, (err, salt) => {
if (err) {
reject(err);
} else {
resolve(salt);
}
});
})
.then(salt => {
return new Promise((resolve, reject) => {
bcrypt.hash(userobject.password_hash, salt, function(err, hash) {
if (err) {
reject(err)
} else {
resolve(hash)
}
})
})
})
.then(hash => {
userobject.password_hash = hash; // store hash in user obj
var user = new User(userobject);
return user.save() // save user in mongoDB
})
.catch(function(err) {
console.log(err);
});
}
After doing some more digging in the change logs of bcryptjs I found out that they added promises but did not update the documentation.. The genSalt en hash methods will return a promise if the callbacks are omitted. 在对bcryptjs的更改日志进行了更多挖掘之后,我发现它们添加了promise但没有更新文档。.如果省略了回调,那么genSalt en hash方法将返回promise。 This would translate to:
这将转换为:
this.addUser = function(userobject) {
return bcrypt.genSalt(10).then((salt) => {
return bcrypt.hash(userobject.password, salt).then((hash) => {
userobject.password_hash = hash;
var user = new User(userobject);
return user.save();
});
});
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.