MEAN节点js承诺返回undefinded

时间:2017-04-20 06:09:06

标签: node.js q

我有一个功能,列出所有用户和参与组的角色。现在我有其他功能,用户角色refid并返回组名称。在尝试返回名字时,我得到了承诺待决状态。

function getAll() {
    var deferred = Q.defer();

    db.users.find().toArray(function(err, users) {
        if (err) deferred.reject(err.name + ': ' + err.message);

        // return users (without hashed passwords)
       users = _.map(users, function(user) {
           //console.log(user);

           return _.omit(user, ['hash']);
           });
       users = _.map(users, function(user){
            refId = {}= user['role'][0]['oid']['_id'];
            //console.log(typeof refId);
            user = _.omit(user, ['role']);
            user.role = userRole.userRole(refId).then(function(err,rid){
                if(err){
                    deferred.reject(err.name+':'+err.message);
                }
                deferred.resolve();
                console.log(deferred.resolve(rid));
                return deferred.promise;
                console.log(deferred.promise);
            });
            return user;
            //console.log(user);

       })
      // getRefId(users)
       //console.log(users);

    deferred.resolve(users);
});

function userRole(rid){
    return new Promise((resolve, reject) => {
        db.groups.findOne({"_id":rid}, function(err, doc){
            if(err){
                reject(err.name + ':' + err.message);

            }
            if(doc){
                resolve({"name": doc.name});
                //console.log(doc.name);
            }
        })
    })
}

1 个答案:

答案 0 :(得分:0)

你想要使用Mongoose的Promises或你似乎在这里做的Node的本地Mongo驱动程序,你不必在任何地方使用new Promise()。你可以直接使用承诺。

参见文档:

  

官方MongoDB Node.js驱动程序提供基于回调和基于Promised的MongoDB交互,允许应用程序充分利用ES6中的新功能。

  

Mongoose异步操作,如.save()和查询,返回Promises / A +一致的promise。这意味着您可以执行MyModel.findOne({})。then()之类的操作并生成MyModel.findOne({})。exec()(如果您正在使用co)。

而不是:

function userRole(rid){
    return new Promise((resolve, reject) => {
        db.groups.findOne({"_id":rid}, function(err, doc){
            if(err){
                reject(err.name + ':' + err.message);

            }
            if(doc){
                resolve({"name": doc.name});
                //console.log(doc.name);
            }
        })
    })
}

你应该可以使用:

function userRole(rid){
  return db.groups.findOne({ _id: rid });
}

或:

const userRole = rid => db.groups.findOne({ _id: rid });

现在,在您的版本中存在一个问题 - 如果没有错误但是返回的doc是假的,则承诺永远不会得到解决,这可能发生。但是,如果您调用的方法首先返回承诺,那么创建自己的承诺就没有意义了。

即使您想要自定义错误消息,您仍然可以使用:

function userRole(rid){
  return db.groups.findOne({ _id: rid })
    .catch(function (err) {
      return Promise.reject(err.name + ':' + err.message);
    });
}

或更现代的语法:

const userRole = rid => db.groups.findOne({ _id: rid })
  .catch(err => Promise.reject(`${err.name}:${err.message}`));