mongoDB 承诺过早返回 [英] mongoDB promise gets returned too early

查看:16
本文介绍了mongoDB 承诺过早返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I just started trying to implement Promises on my Node.js app. Right now i'm checking if a user and password exists then using mongodb to look them up if user isn't found it sets promise.reject() but it is returning the promise too early and it's still in the pending state. If anyone can help or give me ideas on how to refactor it would be much appreciated.

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

推荐答案

这是它在仍处于挂起状态时返回 promise 的预期行为.

It is the expected behavior it returns the promise while it is still in the pending state.

你应该使用then()来检查promise解析.

You should use then() to check for promise resolution.

还有一点是,开始使用promise时不应该使用传统的mongo接口,而是promisify Collection原型的所有方法,这样就可以返回mongo find创建的Promise方法及其 thenable 链.否则我看不到使用承诺的意义.您这样做的方式不会减少您必须编写的代码量.

Another thing is that you should not use the traditional mongo interface when starting to work with promises, but rather promisify all method of the Collection prototype, so you can return the Promise created by the mongo find method with its chain of thenable. Otherwise I don't see the point of using promises. The way you do does not reduce the amount of code you have to write.

顺便说一句,恕我直言,你应该使用 bluebird 而不是 Q,因为它是目前唯一一个不是特别慢的承诺库.

By the way, IMHO you should use bluebird rather than Q, as it is at the moment the only promise library which is not extremely slow.

示例:

在 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...

在其他地方,以你的为例:

elsewhere, taking your example :

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
  }
}

这篇关于mongoDB 承诺过早返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆