Как использовать асинхронное ожидание с обещанием получить мой результат? - PullRequest
1 голос
/ 07 ноября 2019

У меня есть функция, которая должна возвращать результат,

У меня есть массив, для которого я делаю foreach, и я выбираю данные из базы данных с функцией с обещанием для каждого идентификатора в массиве, когдавызывая эту последнюю функцию, я использую async await, но окончательный результат возвращается до выполнения функций.

Пользователь контроллера

myFunction: function (req, res) {
    let headerAuth = req.headers['authorization'];
    let login = utils.getUser(headerAuth);
    if (login) {
        //some function to get data from database
        ModelUsers.getData(login, function (err1, result) {
            if (!err1) {
                let data = [];
                result.forEach(async function (r) {
                    //function with promise, see next
                    let dataxx = await ModelUsers.getDataWithPromise(r._id);
                    data.push(dataxx);
                    console.log("**dataxx : ", dataxx)
                })

                res.json({ success: true, data: data })
            }
        })


    }
},

 ** Model Users **

module.exports.getDataWithPromise = function(id) {
    return new Promise((resolve, reject) => {

        Users.findOne({ _id: id })

            .exec(function (err, doc) {
                resolve(doc)
            })

    })

}

Я получаю пустой результат и вконсоль, у меня отображается результат после успешного возврата вызова

{
    "success": true,
    "data": []
}
GET /users/myFunction 200 21.379 ms - 26
**dataxx :  {mydata:[{"a": 1, "b":2}, {"c":3, "d":4}]}

как я могу получить результат?

Ответы [ 4 ]

1 голос
/ 07 ноября 2019

forEach метод не поддерживает async функции. Вы можете выполнить трюк, используя Array.map, чтобы превратить каждое из значений в обещание, а затем подождать, пока они завершатся с Promise.all:

ModelUsers.getData(login, async function (err1, result) {
    if (!err1) {
        const data = await Promise.all(result.map(({_id}) => ModelUsers.getDataWithPromise(_id)))
        res.json({success: true, data})
    }
})
1 голос
/ 07 ноября 2019

Вы можете исправить это двумя способами, перечисленными ниже:

if (login) {
  //some function to get data from database
  ModelUsers.getData(login, function(err1, result) {
    if (!err1) {
      let data = [];
      result.forEach(async function(r, idx) {
        //function with promise, see next
        let dataxx = await ModelUsers.getDataWithPromise(r._id);
        data.push(dataxx);
        console.log("**dataxx : ", dataxx)
        if (result.length === idx + 1) {
          res.json({
            success: true,
            data: data
          })
        }
      })
    }
  })
}

ИЛИ

if (login) {
  //some function to get data from database
  ModelUsers.getData(login, async function(err1, result) {
      if (!err1) {
        let data = [];
        for (const r of result) {
          //function with promise, see next
          let dataxx = await ModelUsers.getDataWithPromise(r._id);
          data.push(dataxx);
          console.log("**dataxx : ", dataxx)
        })
      res.json({
        success: true,
        data: data
      })
    }
  })
}
1 голос
/ 07 ноября 2019

forEach является асинхронным. Цикл for или for of является синхронным. В этом случае можно использовать цикл for of. Я добавил пример. Обратите внимание на ключевое слово async в ответном вызове getData.

  myFunction: function(req, res) {
   let headerAuth = req.headers['authorization'];
   let login = utils.getUser(headerAuth);
   if (login) {
     //some function to get data from database
     ModelUsers.getData(login, async function(err1, result) {
       if (!err1) {
         let data = [];

         for (let user of result) {
           let dataxx = await ModelUsers.getDataWithPromise(r._id);
           data.push(dataxx);
         }

         res.json({ success: true, data: data })
       }
     })


   }
 }
1 голос
/ 07 ноября 2019

Изменить цикл foreach на цикл for и работать как положено

myFunction: function (req, res) {
let headerAuth = req.headers['authorization'];
let login = utils.getUser(headerAuth);
if (login) {
    //some function to get data from database
    ModelUsers.getData(login, async function (err1, result) {
        if (!err1) {
            let data = [];
            for (let index = 0; index < result.length; index++) {
                const element = result[index];
                let dataxx = await ModelUsers.getDataWithPromise(r._id);
                data.push(dataxx);
            }
            res.json({ success: true, data: data })
        }
    })


}
...