2014-02-12 64 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