0

I have the following promise :

var aggregatePromise = () => {
    return new Promise((resolve, reject) => {
      EightWeekGamePlan.aggregate([
        {
          $match: {
            LeadId: { $in: leads },
            Week: week
          }
        },
        {
          $group: {
            _id: {
              LeadId: "$LeadId"
            },
            total: { $sum: "$TotalClaimsToBeClaimedByClientType" }
          }
        },
        {
          $match: {
            total: { $lte: 5 - howManyClaims }
          }
        }
      ])
        .then(leads => {
          if (leads !== null) {
            resolve(leads);
          } else {
            reject("Couldn't find any Leads");
          }
        })
        .catch(err => {
          reject(err);
        });
    });
  };

I call it here :

  // Step 2
  var callAggregatePromise = async () => {
    var result = await aggregatePromise();
    return result;
  };

And use it here :

 //Step 3: make the call
  callAggregatePromise().then(result => {
    const winners = result.map(m => ({
      LeadId: m._id.LeadId
    }));
    const flattened = winners
      .reduce((c, v) => c.concat(v), [])
      .map(o => o.LeadId);
    console.log(flattened);

    // Step 4 - declare 2ND Promise
    var updateLeadsPromise = () => {
      return new Promise((resolve, reject) => {
        EightWeekGamePlan.updateMany(
          {
            LeadId: {
              $in: flattened
            },
            TargetedToBeClaimedByClientType: groupTarget,
            Week: week
          },
          {
            $inc: {
              TotalClaimsToBeClaimedByClientType: howManyClaims
            }
          }
        )
          .then(leadsUpdated => {
            if (leadsUpdated !== null) {
              resolve(leadsUpdated);
            } else {
              reject("Failed to update requested leads!");
            }
          })
          .catch(err => {
            reject(err);
          });
      });
    };

    //Step 5 : Call 2ND promise
    var callUpdateLeadsPromise = async () => {
      var resAgg = await updateLeadsPromise();
      return resAgg;
    };

    //Step 6 : make the call to the "updateLeadsPromise"
    callUpdateLeadsPromise().then(result1 => {
      console.log(result1);
      if (result1.ok === 1) {
        // TODO
      }
    });
  });

The problem is that Step 4)5)6) are dependent on the result of step 3).

How can I break the chain and make them independent ?

JAN
  • 21,236
  • 66
  • 181
  • 318
  • 1
    Not sure exactly what you're trying to do, but for independent operations you would typically create separate promises and track them all with `Promise.all()` or `Promise.allSettled()` depending upon which reject behavior you want. – jfriend00 Dec 28 '19 at 18:57
  • just dont use await, start two different promises – Dmitry Reutov Dec 28 '19 at 19:02
  • @jfriend00, I guess Promise.all is using when you want to execute promises result in one place since it allows to run the function with all results together...If you dont need it - you can just start two different promises and thats it – Dmitry Reutov Dec 28 '19 at 19:03
  • 2
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Dec 28 '19 at 19:04
  • `callAggregatePromise` and `callUpdateLeadsPromise()` are totally superfluous. You can (and should) just call `aggregatePromise()` resp. `updateLeadsPromise()` directly. – Bergi Dec 28 '19 at 19:06
  • What exactly do you mean by "independent"? Do you want to move the declaration of `updateLeadsPromise` outside of the `then` handler and pass `flattened` by parameter instead of by closure? – Bergi Dec 28 '19 at 19:07
  • 1
    @DmitryReutov - Yes. `Promise.all()` or `Promise.allSettled()` would be used when some piece of code wants to know when everything is done. If that's not the case, then just launch multiple separate promises and handle them each individually in their own chain. The OP's question is not clear to me what the desired spec is. – jfriend00 Dec 28 '19 at 19:17
  • There's just one asynchronous dependency; `step 4` is dependent on the result delivered by `aggregatePromise()`. In order to realise that dependency, `step 4` must be either nested (as in the question) or chained off the `aggregatePromise()` call (or the equivalent `async`/`await` syntax`). Full independence is not possible. – Roamer-1888 Dec 29 '19 at 02:22

1 Answers1

1

To break a chain you will have to await the Promises in order. It will still be a chain but in a different format. Btw throw away step 2 and 5.

To use await you have to have it inside a async function.

async function doLeadStuff() {

    // awaiting main Promise
    const result = await aggregatePromise();

    const winners = result.map(m => ({
        LeadId: m._id.LeadId
    }));

    const flattened = winners
        .reduce((c, v) => c.concat(v), [])
        .map(o => o.LeadId);
    console.log(flattened);

    // awaiting updates
    const leadsUpdated = await EightWeekGamePlan.updateMany(
        {
            LeadId: {
                $in: flattened
            },
            TargetedToBeClaimedByClientType: groupTarget,
            Week: week
        },
        {
            $inc: {
                TotalClaimsToBeClaimedByClientType: howManyClaims
            }
        }
    )
    if (leadsUpdated === null) {
        throw new Error("Failed to update requested leads!");
    }

    console.log(result1);
    if (result1.ok === 1) {
        // TODO
    }


}

// calling async function
doLeadStuff()
fubar
  • 383
  • 2
  • 11