Node.js Mongoose Promise迷路了

我有一个mongoDB的Node.js API。 有一个创build用户的路由,需要散列密码,为此我使用bcryptjs包。

路线如下所示:

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

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

我得到一个错误:“不能读取属性”,然后“未定义”,这告诉我,我没有收到来自addUser的承诺。 我看,bcryptjs悲伤不使用承诺,然而,mongoose呢。 (添加这个:

 var mongoose = require('mongoose').Promise = Promise; 

没有帮助)

我试图用拒绝和解决包装function在一个承诺,但是这给了这个错误:“TypeError:Promiseparsing器undefined不是一个函数”。

如何获得mongoose的save()函数返回到post过程中的.then()的承诺? 我试图在两个bcrypt函数前面添加return,但是这也不起作用。

任何build议,欢迎!

你的addUser函数nevers返回对调用者的承诺。 你正在从bcrypt.hashcallback函数return ,但这与addUser的返回值无关。

看起来像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 } }); } }); }); }; 

另外请注意,我没有addUser只是吞咽错误; 相反,他们传播给调用者。 调用者应该处理它们(即使“处理”只是logging)。

你不会返回一个Promise表单this.addUser ,你必须将基于bcrypt的callback转换为Promises。 您可以将整个bcrypt API转换为支持基于Promise的函数,例如使用promisifyAll的蓝鸟库,或者像这样手动使用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); }); } 

或者那样:

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

在bcryptjs的更改日志中做了更多的挖掘之后,我发现他们添加了promise,但没有更新文档。如果省略了callback,genSalt和hash方法将返回一个promise。 这将转化为:

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