let shouldHavePaid = 0;
demographicsArray.map((country) => {
if (country.checked == true) {
Price.findOne({ country: country._id }).then((priceRes) => {
if (priceRes) {
shouldHavePaid = shouldHavePaid + priceRes.priceSMS * country.count;
} else {
shouldHavePaid = shouldHavePaid + 0.1 * country.count; //Default price for unlisted countries
}
});
}
});
console.log(`Finish: ${shouldHavePaid}`);
我希望最后的console.log在映射后执行,但是会在映射完成之前触发。 我期待这个输出,因为据我所知映射应该是同步的而不是异步的。我相信对DB的请求搞砸了吗?您在这里有什么建议?
答案 0 :(得分:2)
您可以结合使用Promise.all
和await:
await Promise.all(demographicsArray.map(async (...)=>{
if (...) {
await Prize...
if (priceRes) {
....
}
}
})
console.log(...)
仅在诺言完成后,才可以在async
函数中使用Await来运行下一行。 Promise.all()
使您可以等待一系列的承诺。将回调标记为async
会使它返回承诺,Promise.all()
可以使用该承诺。它还允许您在函数内部使用await,因此您不必使用.then()
。
答案 1 :(得分:0)
嗯,你说的是你自己的事
我期望此输出,因为据我所知地图应该同步 而不是异步的。我相信发给数据库的请求搞砸了吗?
您的Price.findOne(expr)
返回一个Promise,因此这部分是异步的,因此这是问题的根源。
要使console.log结尾,并且不对代码进行重构,只要将其放入实际记录(如果已获取并比较数据)之后即可!
let shouldHavePaid = 0;
demographicsArray.map((country) => {
if (country.checked == true) {
Price.findOne({ country: country._id }).then((priceRes) => {
if (priceRes) {
shouldHavePaid = shouldHavePaid + priceRes.priceSMS * country.count;
} else {
shouldHavePaid = shouldHavePaid + 0.1 * country.count; //Default price for unlisted countries
}
console.log(`Finish: ${shouldHavePaid}`);
});
}
});