如何使用 async await 和 promise 来获得我的结果?

How to use async await with promise to get my result?

我有一个函数应该 return 结果,

我有一个数组,我在上面创建了一个 foreach,我使用一个函数从数据库中获取数据,该函数承诺数组中的每个 id, 调用最后一个函数时,我使用异步等待,但最终结果是 returned before functions are executed.

控制器用户

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

    })

}

我收到一个空结果,在控制台中,我在 returned 调用成功后显示了结果

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

我怎样才能得到结果?

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


}

您可以通过以下两种方式解决此问题:

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

forEach 是异步的。 forfor of 循环是同步的 for of 循环可用于这种情况。我添加了一个例子。请注意 getData 回调中的 async 关键字。

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


   }
 }

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