从异步调用返回 Mongoose 查询结果

returning Mongoose query result from Async call

我正在解决一个问题,我需要在数据库中查询选民实例,并使用该实例更新选举,return查看原始函数是否更新成功或不。我的代码目前看起来像这样:

function addCandidatesToElection(req, res) {
    let electionName = req.body.electionName;
    let candidates = req.body.candidates;
    let addedCandidatesSucessfully = true;
    for(let i=0; i<candidates.length; i++) {
        addedCandidatesSucessfully = _addCandidateToElection(electionName, candidates[i]);
        console.log("added candidates sucessfully:" + addedCandidatesSucessfully);
    }
    if(addedCandidatesSucessfully) {
        res.send("createElection success");
    } else {
        res.send("createElection fail");
    }
}

调用此函数的函数:

function _addCandidateToElection(electionName, candidateName) {
    async.parallel(
    {
        voter: function(callback) {
            Voter.findOne({ 'name' : candidateName }, function(err,voter) {
                callback(err, voter);
            });
        }
    },
    function(e, r) {
        if(r.voter === null){ 
            return 'Voter not found';
        } else {
            Election.findOneAndUpdate(
            {'name': electionName },
            {$push: { candidates: r.voter }},
            {new: true},
            function(err, election) {
                if(err){ return err; } 
                return (election) ? true : false;
                });
            }
        }
    );
}

我已经尝试打印出 Voter 实例 (r.voter) 以检查它是否存在(确实存在),并且还打印出由 mongoose 调用 returned 的选举对象,这也有效。但是,我在

中得到一个空值
addedCandidatesSucessfully = _addCandidateToElection(electionName, candidates[i]);

行,不管调用结果如何。我认为这与 mongoose 调用 returning 本地值有关,该本地值永远不会 returned 到调用 _addCandidateToElection 的函数,但我不知道我应该如何 return .我试过放置控制标志,例如

let foundAndUpdatedElection = false;

在 _addCandidateToElection 的第一行并在 Mongoose 查询的回调中更新它,但显然它没有改变。 我应该如何 return 将查询结果传递给 addCandidatesToElection 函数?

您可能应该 'promisify' 您的代码可以帮助您更好地处理 js 的异步特性。尝试以下而不是您的示例:

function findVoter(candidateName) {
  return new Promise(function(resolve, reject) {
    Voter.findOne({ 'name' : candidateName }, function(err,voter) {
      if(error) {
        reject(error);
      } else { 
        resolve(voter);
      }
    });
  });
}

function addCandidateToElection(electionName, candidateName) {
  return findVoter(candidateName).then(function(voter) {
    return new Promise(function(resolve, reject) {
        Election.findOneAndUpdate(
          {'name': electionName },
          {$push: { candidates: voter }},
          {new: true},
          function(err, election) {
            if (err) {
              reject(err);
            } else {
              resolve(!!election);
            }
          });
  });
}

function addCandidatesToElection(req, res) {
  let electionName = req.body.electionName;
  let candidates = req.body.candidates;
  let addedCandidatesSucessfully = true;
  let candidatePromiseArray = [];
  for(let i=0; i<candidates.length; i++) {
    candidatePromiseArray.push(addCandidateToElection(electionName, candidates[i]));
  }
  Promise.all(candidatePromiseArray)
    .then(function(results) {
      console.log(results);
      res.send('create election success');
    })
    .catch(function(error) {
      console.error(error);
      res.send('failed');
    });
}

您也将不再需要使用异步库,因为 promises 现在在 ES6 中是原生的