我有一个应该返回结果的函数,
我有一个在其上进行foreach的数组,并且我从数据库中获取了一个函数,该函数对数组中的每个id都有一个承诺, 调用此最后一个函数时,我使用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, 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}]}
我如何获得结果?
答案 0 :(得分:1)
将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 })
}
})
}
答案 1 :(得分:1)
您可以通过以下两种方式解决此问题:
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
})
}
})
}
})
}
OR
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
})
}
})
}
答案 2 :(得分:1)
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 })
}
})
}
}
答案 3 :(得分:1)
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})
}
})