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