简体   繁体   中英

Wait for map to end before continuing

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

I want the console.log at the end to execute after the map, but it fires before the map is finished. I am expecting this output because as far as I know map should be sync and not async. I believe that the request to the DB messes it up? what would you suggest here?

You can use Promise.all in combination with await:

await Promise.all(demographicsArray.map(async (...)=>{
    if (...) {
        await Prize... 
        if (priceRes) {
            ....
        }
    }
})

console.log(...)

Await can be used in async functions to run the next line only after the promise completes. Promise.all() allows you to wait for a whole array of promises. Marking the callback as async makes it return a promise, that can be used by the Promise.all() . It also allows you to use await inside the function so you don't have to use .then() .

Well, you are saying it your self pretty much

I am expecting this output because as far as I know map should be sync and not async. I believe that the request to the DB messes it up?

Your Price.findOne(expr) returns a promise, so this part is async, so this is the root of your problem.

For your console.log to come at the end, and without making restructs to your code, just put it after the actuall record if fetched and the data compared!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM