Как сделать асинхронную функцию в контроллере с помощью API узла - PullRequest
0 голосов
/ 21 сентября 2018

Я застрял, я хотел бы получить все оценки для fablab и не могу сделать код асинхронным.Итак, здесь я получаю пустой массив, так как код не асинхронный.

Это мой пример:

// get all ratings for a fablab
rating_router.get('/get/:id', (req, res) => {
  Fablab.findById({_id:req.params.id}, (err, fablab) => {
    if(err) send(err)
    else {

      let ratingstest = []
      fablab.rating.map(ratingID =>  {
        Rating.findById({_id:ratingID}, (err, rating) => {
          if(err) send(err)
          else ratingstest.push(rating)
        })
      })

      return ratingstest
    }
  })
})

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Вы можете добавить условие, чтобы проверить, когда разрешается последний запрос, и затем передать массив результатов в res.send:

rating_router.get('/get/:id', (req, res) => {
  Fablab.findById({ _id: req.params.id }, (err, fablab) => {
    if (err) {
      res.send(err)
    }
    else {
      let ratingstest = []

      fablab.rating.forEach(ratingID => {
        Rating.findById({ _id: ratingID }, (err, rating) => {
          if (err) {
            res.send(err)
          }
          else {
            ratingstest.push(rating)

            // Check if this is the last one
            if (ratingstest.length == fablab.rating.length) {
              res.send(ratingstest)
            }
          }
        })
      })
    }
  })
})

Однако, возможно, было бы лучше использовать обещания:

rating_router.get('/get/:id', (req, res) => {
  Fablab
    .findById({ _id: req.params.id })
    .then(fablab => fablab.rating || [])
    .then(ratingIDs => ratingIDs.map(ratingID =>
      Rating.findById({ _id: ratingID })
    ))
    .then(ratingArr => Promise.all(ratingArr))
    .then(result => res.send(result))
    .catch(err => res.send(err))
})

Надеюсь, это поможет.

0 голосов
/ 21 сентября 2018

Внутри функции отображения создайте обещание findById

function findByIdPromise(){
    return new Promise((resolve,reject)=>{
        Rating.findById({_id:ratingID}, (err, rating) => {
            if(err) reject(err)
            else {
                ratingstest.push(rating)
                resolve()
            }
        })
    })
}

После завершения отображения вы получите массив обещаний, а затем просто выполните

Promise.all(fablab.rating).then(()=>console.log(ratingstest))

...