Javascript Node.js Mongoose承诺丢失

Javascript Node.js Mongoose承诺丢失,javascript,node.js,mongoose,promise,bcrypt,Javascript,Node.js,Mongoose,Promise,Bcrypt,我有一个带有mongoDB的Node.js API。有一个路由创建用户并需要散列密码,为此我使用bcryptjs包 路线如下所示: router.route('/user') .post(function(req, res) { if(req.body.password === req.body.passwordConfirm) { userManager.addUser(req.body) .then(funct

我有一个带有mongoDB的Node.js API。有一个路由创建用户并需要散列密码,为此我使用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);
                    });
                }
            });
        }
    });
};
我得到一个错误:“无法读取未定义的属性'then',这告诉我我没有收到addUser的承诺。我看了看,bcryptjs不幸地没有使用承诺,然而,猫鼬使用。 (加入:

var mongoose = require('mongoose').Promise = Promise;
(没有帮助)

我尝试用reject和resolve将函数包装在一个承诺中,但这会产生以下错误:“TypeError:promise resolver undefined不是一个函数”

如何保证mongoose的save()函数返回post路由中的.then()?我尝试在两个bcrypt函数前面添加return,但也没有成功


欢迎提出任何建议

您的
addUser
函数nevers将承诺返回给其调用者。您正在从
bcrypt.hash
回调函数执行
return
,但这与
addUser
的返回值无关

看起来,
addUser
必须使用一些未启用承诺的API,因此您必须执行
newpromise
,类似这样的操作(请参见
***
注释):


还要注意的是,我没有
addUser
只是吞咽错误;相反,它们被传播到调用方。调用者应该处理它们(即使“处理”只是日志记录)。

您没有从
中返回承诺。addUser
,您必须将基于回调的
bcrypt
转换为承诺。您可以使用bluebird库等将整个
bcrypt
API转换为支持基于承诺的函数,或者使用
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的更改日志进行了进一步挖掘之后,我发现他们添加了承诺,但没有更新文档。。如果省略回调,genSalt en散列方法将返回一个承诺。这将转化为:

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

你没有从你的
this.addUser
中返回承诺。要明确的是,你没有从
this.addUser
@Jaromanda X返回任何东西。是的,我现在明白了,我对承诺是陌生的,我想我被不支持承诺的API迷住了。。
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();
        });
    });
};