2017-08-09 84 views
0

我正在处理一个问题,我需要查询数据库的选民实例,并使用该实例更新选举,返回到原始功能,无论该更新是否成功或不。我的代码目前看起来是这样的:从异步调用返回Mongoose查询结果

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

我已经尝试打印出选民实例(r.voter),以检查它是否存在(它) ,并打印出由猫鼬呼叫返回的选举对象,这也起作用。但是,无论调用的结果如何,我都会得到一个空值,其值为

addedCandidatesSucessfully = _addCandidateToElection(electionName, candidates[i]); 

行。我认为它与mongoose调用有关,返回一个本地值,该值永远不会返回到调用_addCandidateToElection的函数,但我不知道该如何返回。我试图把控制标志,如

let foundAndUpdatedElection = false; 

上_addCandidateToElection的第一行,并更新它的猫鼬查询的回调中,但显然它不会改变。 我该如何将查询结果返回给addCandidatesToElection函数?

回答

0

您应该'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'); 
    }); 
} 

你也将不再需要,因为承诺现在是在本土ES6

+0

意想不到的答案,谢谢使用异步库!我正在考虑使用Promises,但是在蓝鸟和Mongoose自己的承诺实施之间我有点失落。但是这样更具可读性,正如你所说的,它捆绑了ES6,这非常棒。在有人读这个的情况下,我还必须修改if(err)在findVoter到if(err ||!voter)的行,否则Mongoose将在稍后尝试将null值推送到Promise数组。除此之外,与这个答案了解了很多,谢谢:) –

+0

很高兴它帮助! – ruedamanuel