javascript - Wait for map to end before continuing - Stack Overflow

let shouldHavePaid = 0;demographicsArray.map((country) => {if (country.checked == true) {Price.findOn

  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?

  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?

Share Improve this question asked Jun 29, 2020 at 15:17 PastaLoverPastaLover 4915 silver badges22 bronze badges 3
  • 3 1. Please don't use .map for a simple iteration. Use a loop or .forEach for that. 2. .map is a synchronous operation, but you are launching asynchronous ones inside it. You either need to make all async and use Promise.all and wait for all of the pletion (parallel) or convert to a regular loop and await every iteration (sequential). You can also reduce to a single sequential operation but I'd probably go with the loop. – VLAZ Commented Jun 29, 2020 at 15:21
  • Thanks, and why do you suggest not to use map for simple iterations? For the ability to use await? – PastaLover Commented Jun 29, 2020 at 15:46
  • 1 It's the wrong tool and it's misleading. Mapping operations are 1:1 transformations. Using it for anything else is sending the wrong message to anybody who would be looking at the code in the future, including yourself. .map is an idiom in JavaScript and many other languages. There are many other better idioms for mon array operations. Check my profile information. – VLAZ Commented Jun 29, 2020 at 15:51
Add a ment  | 

2 Answers 2

Reset to default 6

You can use Promise.all in bination 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 pletes. 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 e at the end, and without making restructs to your code, just put it after the actuall record if fetched and the data pared!

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745496907a4630231.html

相关推荐

  • javascript - Wait for map to end before continuing - Stack Overflow

    let shouldHavePaid = 0;demographicsArray.map((country) => {if (country.checked == true) {Price.findOn

    9小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信