等待地图结束再继续

时间:2020-06-29 15:17:51

标签: javascript node.js asynchronous async-await

  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的请求搞砸了吗?您在这里有什么建议?

2 个答案:

答案 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}`);
      });
    }
  });