Nodejs等待查询

时间:2019-01-22 22:05:50

标签: node.js mongodb express mongoose promise

我正在将Nodejs与MongoDB(mongoose和express)一起使用。

由于我不信任用户数据,因此需要从数据库中进行验证。

输入数据:

{
 "id": "someid",
 "nottrusteddata": [ {"id": "1"}, {"id" :"2"}]
}

在我的职能中,我正在验证数据:

router.post("/validate", (req, res,next) =>{
  let validated_data = validate_data(req); 
  console.log(JSON.stringify(validated_data));
  const mydata = new Mydata({
     id: req.body.id,
     lst : validated_data   
  });
  console.log("mydata: " + JSON.stringify(mydata));
  /* Some Usefull stuff is here */
  res.status(200).json();
}

function validate_data(req){
 let validated_data = []
 for(let i = 0; i < req.body.nottrusteddata.length; i++)
 {
   Databaseobject.findOne({'id': req.body.nottrusteddata[i].id})
   .exec()
   .then(dbobject =>{
     if(dbobject) // not undefined, it exists in the database
     {
       // Some logic with the object returned from the database
       let tmp_object = {};
       tmpobject.id = dbobject.id;
       // Append it to the list, so that the upper function can use it
       validated_data.push(tmp_object);
     }
   })
 }
 return validated_data;
}

所需的输出应包含来自数据库的正确信息,但是,由于nodejs的异步特性,validated_data返回null。

我也尝试使用Promise。我无法成功。

const validate_data = function(req){
  return new Promise(function(resolve,reject){

     let validated_data = []
     for(let i = 0; i < req.body.nottrusteddata.length; i++)
     {
       Databaseobject.findOne({'id': req.body.nottrusteddata[i].id})
       .exec()
       .then(dbobject =>{
         if(dbobject) // not undefined, it exists in the database
         {
           let tmp_object = {};
           tmpobject.id = dbobject.id;
           validated_data.push(tmp_object);
         }
       })
     }
     resolve(validated_data);
  }
}

我在做什么错?我如何等待数据库查询完成,然后执行主要部分?如果只有一个验证,则可以使用.then()。但是,该列表可能包含许多元素,我需要等待所有元素被验证。

1 个答案:

答案 0 :(得分:1)

您的Databaseobject.findOne()调用是异步的,因此您的诺言将在它们中的任何一个完成之前解决。

您可以使用Promise.all等到所有诺言都解决。

希望这对您有用:

router.post("/validate", (req, res) => {

  validate_data(req.body.nottrusteddata)
    .then(validated_data => {
      const mydata = new Mydata({
        id: req.body.id,
        lst: validated_data   
      })

      // Some useful stuff is here

      res.status(200).json()
    })
    .catch(err => {
      // Handle error
    })

}

function validate_data(nottrusteddata) {

  // Create array of pending promises
  const promises = nottrusteddata
    .map(item => {
      return Databaseobject
        .findOne({ 'id': item.id })
        .exec()
    })

  // Wait for all promises to resolve
  return Promise.all(promises)
    .then(docs => {
      return docs
        .filter(dbobject => dbobject) // Filter out undefined
        .map(dbobject => {
          return { id: dbobject.id }
        })
    })

}

如果需要,还可以在此处使用 async-await

router.post("/validate", async (req, res) => {

  try {
    const validated_data = await validate_data(req.body.nottrusteddata)

    const mydata = new Mydata({
      id: req.body.id,
      lst: validated_data   
    })

    // Some useful stuff is here

    res.status(200).json()
  }

  catch(err) {
    // Handle error
  }

})