Nodejs ждут запроса - PullRequest
       6

Nodejs ждут запроса

0 голосов
/ 23 января 2019

Я использую 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;
}

Требуемый вывод должен содержать правильную информацию, поступающую из базы данных, однако, из-за асинхронной природыиз узлаjs validated_data возвращает ноль.

Я также пытался использовать 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 голосов
/ 23 января 2019

Ваши 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
  }

})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...