如何打印来自Promise函数的结果

时间:2017-01-04 11:49:38

标签: javascript node.js promise bluebird q

我刚开始学习Promises,我得到控制台结果 [Promise {pending}] 我想打印来自该函数的Exact结果,有人可以帮我解决这个问题。

exports.listProjectRepos1 = (req, res)=> {
    let pID = mongoose.Types.ObjectId(req.params.projectId);
    console.log("User Id is ", req.user._id);
    let query = {
        userID: mongoose.Types.ObjectId(req.user._id),
        projectID: pID
    };
        RepositoriesSchema.find(query).lean().then((repos)=> {
            return repos
        }).then((repos)=> {
            let roots = repos.map(exports.populateCodestack1);
            console.log(roots);// trying to Print the Results here
        });
};


exports.populateCodestack1 = function (repo) {
    return new Promise((resolve, reject)=> {
        Promise.all([new Promise((resolve, reject)=> {
            let codeId = repo.codeStack;
            CodeStacksSchema.findOne({ID: codeId}).lean().exec(function (err, codeStack) {
                if (codeStack) {
                    repo.stack = codeStack.name;
                    resolve(repo)
                }
            });
        }),
            new Promise((resolve, reject)=> {
                let owner = mongoose.Types.ObjectId(repo.SCMAccount);
                console.log("Owner Id is", owner);
                ScmaAccount.findOne({_id: owner}).lean().exec(function (err, scm) {
                    if (scm) {
                        repo.type = scm.type;
                        resolve(repo);
                    }
                });
            })

        ]).then(function (result1) {
           // console.log("Refresh Result",result);
            resolve(result1);
        })
    })
};

我想打印函数的输出。

1 个答案:

答案 0 :(得分:3)

exports.populateCodestack1会返回一个Promise,因此roots将包含一个Promise列表。

如果你想等到阵列中的所有Promise都被解决,那么你可以将它传递给Promise.all

RepositoriesSchema.find(query).lean()
  .then( repos => Promise.all(repos.map(exports.populateCodestack1)) )
  .then( roots => {
    console.dir(roots);
  });

旁边:如果你使用new Promise那么你应该处理你的错误情况,如果你需要包装一个不支持promises的函数,但只使用new Promise,但永远不要包装现有的Promise对象:

exports.populateCodestack1 = function(repo) {
  return Promise.all([
    new Promise((resolve, reject) => {
      let codeId = repo.codeStack;
      CodeStacksSchema.findOne({
        ID: codeId
      }).lean().exec(function(err, codeStack) {
        if (err) {
          reject(err);
        } else {
          repo.stack = codeStack.name;
          resolve(repo)
        }
      });
    }),
    new Promise((resolve, reject) => {
      let owner = mongoose.Types.ObjectId(repo.SCMAccount);
      console.log("Owner Id is", owner);
      ScmaAccount.findOne({
        _id: owner
      }).lean().exec(function(err, scm) {
        if (err) {
          reject(err)
        } else {
          repo.type = scm.type;
          resolve(repo);
        }
      });
    })
  ])
};

修改

因为mongoose lib已经支持Promises,所以应该可以使用:

进一步简化它
exports.populateCodestack1 = function(repo) {
  return Promise.all([
    CodeStacksSchema.findOne({
      ID: repo.codeStack
    }).lean().then(codeStack => {
      repo.stack = codeStack.name;
      return repo
    }),
    ScmaAccount.findOne({
      _id: mongoose.Types.ObjectId(repo.SCMAccount)
    }).lean().then(scm => {
      repo.type = scm.type;
      resolve(repo);
    })
  ])
};