我在使用异步调用时遇到了麻烦。这是给我带来麻烦的代码片段
company.find({ managerID: req.session.manager.managerID })
.exec((err, _companies) => {
if(err)
return res.status(500).send({ message: "Uh, oh! Something went wrong." });
else {
var data = [];
var i = 0;
_companies.forEach(c => {
user.find({ companyID: c._id, status: 0})
.then(_user => {
// console.log(_user);
var dummy = {
companyID: c._id,
companyName: c.companyName,
selectedCurrency: c.selectedCurrency,
metrics: c.metrics,
headAdmin: _user[0].email,
headName: _user[0].designer
};
console.log(dummy);
data.push(dummy);
console.log(data);
i++;
}).catch(err => {
return res.status(500).send({ message: "Uh, oh! Something went wrong." });
});
});
if(i == _companies.length)
return res.status(200).send({ data: data });
}
});
我的数据对象是在正确形成对象之前发送的。
我试图从.exec切换到.then,希望它可以修复它,甚至试图仅在循环完成后才返回(甚至不返回空数组)。
每当我在
console.log("hi")
之前调用return res.status(200).send({ data: data})
时,它总是在console.log(dummy)
之前打印会等待解决此问题,如果是,我应该如何使用它,因为我对如何使用它不熟悉?
最佳答案
Array.prototype.forEach
是同步工作的,因此它不会等待内部的异步操作(例如user.find()
)。因此,i == _companies.length
在异步操作完成之前计算为true
。
如另一个答案中所建议,您可以通过将所有待处理的promise收集到数组中并将其传递给Promise.all()来解决此问题。在您的方案中,这可能类似于以下内容:
company.find({ managerID: req.session.manager.managerID })
.exec((err, _companies) => {
if (err) {
return res.status(500).send({ message: "Uh, oh! Something went wrong." });
}
const results = _companies.map(c =>
user.find({ companyID: c._id, status: 0})
.then(_user => ({
companyID: c._id,
companyName: c.companyName,
selectedCurrency: c.selectedCurrency,
metrics: c.metrics,
headAdmin: _user[0].email,
headName: _user[0].designer
}))
);
return Promise.all(results)
.then(data => res.status(200).send({ data: data }))
.catch((err) => res.status(500).send({ message: "Uh, oh! Something went wrong." }));
});
关于node.js - NodeJS异步。在正确形成对象之前发送的标题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58880074/