mongoDB承诺过早返回

时间:2014-02-12 15:57:48

标签: node.js mongodb promise

我刚开始尝试在我的Node.js应用上实现Promises。现在我正在检查用户和密码是否存在,然后使用mongodb查找它们如果找不到用户它设置了promise.reject()但是它过早地返回了promise并且它仍处于挂起状态。如果有人可以帮助或给我关于如何重构的想法,将非常感激。

https://gist.github.com/joshbedo/8957056

1 个答案:

答案 0 :(得分:5)

当它仍然处于暂挂状态时,它会返回承诺的预期行为。

您应该使用then()来检查承诺解决方案。

另一件事是你不应该在开始使用promises时使用传统的mongo接口,而是宣传Collection原型的所有方法,这样你就可以返回由mongo find方法创建的Promise可怜的链子。否则我没有看到使用承诺的意义。你的方式不会减少你必须编写的代码量。

顺便说一句,恕我直言,你应该使用蓝鸟而不是Q,因为它是目前唯一一个非常慢的承诺库。

示例:

db.js中的

var mongoClient = require('mongodb').MongoClient;
var collection  = require('mongodb').Collection;

var Promise     = require('bluebird');

// We promisify everything. Bluebird add ***Async function which return promises.
Promise.promisifyAll(collection.prototype);
Promise.promisifyAll(mongoClient);

//In mongodb cursor is not built from protoype I use to promisify it each time. Not necessary if you don't use cursors.
collection.prototype._find = collection.prototype.find;
collection.prototype.find = function() {
  var cursor = this._find.apply(this, arguments);
  cursor.toArrayAsync = Promise.promisify(cursor.toArray, cursor);
 return cursor;
};

//then you connect to the DB and exports your collections...

其他地方,举个例子:

this.loginUser = function(user) {
  var userid = user.userid,
  var password = (user.password) ?
    crypto.createHash("md5").update(user.password).digest("hex"):
    undefined
  var rememberme = user.rememberme;

  if(userid && password) {
    // we directly return the promise from mongodb, that we chain with a then
    return db.users.findOneAsync({ email: userid, password: password }) // return a promise that we chain
    .then(function(user) { // that we chain
      if(user) {
        var logincode = uuid.v4(),
        var token = jwt.encode({email: userid, password: password}, secret);

        if(rememberme) {
          res.cookie("clogincode", logincode, { magAge: 900000 } );
        }
        return user;  // return in a then callback will just resolve the promise
      } else {
        throw  new Error('User not found'); // throwing in a then callback will just reject the promise
      }
    }); // end of the then, then return a promise that we return (with the return keyword above)
  } else {
    return Promise.reject("Username or Password was not entered"); // this is the only case where we have to actually create a promise ourself
  }
}