2014-02-12 65 views
2

我刚开始尝试在我的Node.js应用上实现Promise。现在我正在检查用户和密码是否存在,然后使用mongodb来查找它们,如果没有找到用户,它会设置promise.reject(),但它太早返回承诺,它仍处于挂起状态。如果任何人可以帮助或给我如何重构的想法,将不胜感激。mongoDB承诺退回得太早

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

+1

作为一个侧面说明:使用的东西比MD5散列更强的密码和我不会” t也依赖uuid作为确认码。 – mnemosyn

+0

是的,它只是让它运行加我不想暴露我的安全模块:p –

+0

请确保您返回第一个defer.reject(err)后,否则defer.reject()将再次调用defer.reject( “用户未找到”) –

回答

5

这是它返回的希望,而它仍处于待处理状态的预期行为。

您应该使用then()来检查承诺解决方案。另一件事是,当你开始使用承诺时,你不应该使用传统的mongo接口,而是会提供原型的所有方法,所以你可以返回由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 
    } 
} 
+0

你碰巧知道IcedCoffeeScript的等待和推迟使用什么?是的,我希望它检查是否设置了变量,然后查询数据库,然后检查结果是否被满足或拒绝。看起来我正在为我的代码库添加更多内容,试图实现该功能。 –

+0

你有喜欢图书馆的mongo like promisify-mongo –

+0

我personnaly使用蓝鸟的promisify方法,基本上可以promisify任何库使用节点样式回调。我不知道Q是否具有相同的功能功能。 – Guilro