0

I have 5 promises waiting to be executed using Promise.All

GenerateWeekWorkPlan = (.....) => {
    return new Promise(async (resolve, reject) => {

        // Some logic 

        // retVal = ... DB Manipulation ... 

          if (retVal !== null) {             
              resolve({
                status: 200,
                msg: "Successfully created ..."
              });
            } else {              
              reject({
                status: 400,
                msg: "Failed to create ..."
              });
            }

    }

}

const promiseWeek1 = this.GenerateWeekWorkPlan(.....);
const promiseWeek2 = this.GenerateWeekWorkPlan(.....);
const promiseWeek3 = this.GenerateWeekWorkPlan(.....);
const promiseWeek4 = this.GenerateWeekWorkPlan(.....);
const promiseWeek5 = this.GenerateWeekWorkPlan(.....);

Promise.all(
      promiseWeek1,
      promiseWeek2,
      promiseWeek3,
      promiseWeek4,
      promiseWeek5
    )
      .then(success => console.log(success))
      .catch(failed => console.log(failed));

The code runs only the first promise and then get stuck. Why doesn't continue to next promises (2-3-4-5) ?

EDIT:

GenerateWeekWorkPlan = (weekNumber, packageId, arrayOfTargets) => {
    return new Promise(async (resolve, reject) => {
      // Get all the raw data from Leads collection that is not Duplicated
      console.log("GenerateWeekWorkPlan ...");
      try {
        // 1. Get leads by package id and take all those which are not duplicated
        const leads1 = await Leads.find({
          Duplicate: false,
          PackageId: packageId
        })
          .lean()
          .exec(async (err, leads) => {
            // docs are plain javascript objects instead of model instances



            const oneWeekWorkPlan = arrayOfTargets.map(target => {
              return leads.map(lead => ({
                        .... 
              }));
            });

            console.log("--------Insert Many----------");
            const flatted = oneWeekWorkPlan.flat();
            console.log(flatted);

            const retVal = await WeekPlangs.insertMany(flatted);
            console.log("--------Done Insert Many----------");
            if (retVal !== null) {
              console.log("retVal" + retVal);
              resolve({
                status: 200,
                msg: "Successfully created documents"
              });
            } else {
              console.log("Nothing inside retVal" + retVal);
              reject({
                status: 400,
                msg: "Failed to create documents"
              });
            }
          });
      } catch (err) {
        console.error(err.message);
        reject({
          status: 400,
          msg: "Failed to create documents"
        });
      }
    });
  };
};
JAN
  • 21,236
  • 66
  • 181
  • 318
  • What do you by gets stuck on how do you know the first promise was resolved? – Igor Nov 12 '19 at 19:12
  • is the wrapper supposed to be async? – dandavis Nov 12 '19 at 19:17
  • @dandavis: Yes ,I'm using await to get stuff from MongoDB – JAN Nov 12 '19 at 19:21
  • there's no await in the code shown though... Promises themselves aren't supposed to be `async` technically, even if they are for sure async practically. – dandavis Nov 12 '19 at 19:26
  • @dandavis: You suggest removing the async from the Promise ? – JAN Nov 12 '19 at 19:27
  • i can't see enough code to say that's 100% the problem, but it seems reasonable, unless something is throwing before that point. – dandavis Nov 12 '19 at 19:29
  • @dandavis: I added the code in the Edit section.Thanks – JAN Nov 12 '19 at 19:31
  • 1
    Wrapping an existing promise inside a `new Promise()` is not necessary and is considered a promise anti-pattern. Just return the promises you already have - no need to wrap them in a new one. Beyond that, I don't understand what the question is asking. – jfriend00 Nov 12 '19 at 19:35

1 Answers1

1

Never pass an async function as the executor to new Promise! It seems you are using it so that you can call resolve and reject from the asynchronous exec() callback - but really you shouldn't have used that callback in the first place. You would want to promisify the call and await it, or in case of MongoDB all you would need to do is drop the callback to get back a promise. Make GenerateWeekWorkPlan itself the async function so that it returns a promise:

async function GenerateWeekWorkPlan(weekNumber, packageId, arrayOfTargets) {
  // Get all the raw data from Leads collection that is not Duplicated
  console.log("GenerateWeekWorkPlan ...");
  try {
    // 1. Get leads by package id and take all those which are not duplicated
    const leads = await Leads.find({
      Duplicate: false,
      PackageId: packageId
    }).lean();
    // docs are plain javascript objects instead of model instances
    const oneWeekWorkPlan = arrayOfTargets.flatMap(target => {
      return leads.map(lead => ({
        …
      }));
    });

    console.log("--------Insert Many----------");
    console.log(oneWeekWorkPlan);
    const retVal = await WeekPlangs.insertMany(oneWeekWorkPlan);
    console.log("--------Done Insert Many----------");
    if (retVal !== null) {
      console.log("retVal" + retVal);
      return {
        status: 200,
        msg: "Successfully created documents"
      };
    } else {
      console.log("Nothing inside retVal" + retVal);
      throw {
        status: 400,
        msg: "Failed to create documents"
      };
    }
  } catch (err) {
    console.error(err.message);
    throw {
      status: 400,
      msg: "Failed to create documents"
    };
  }
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375