0

I wish to call dealCardSelectableAI(), have it chooseCards(), then use the output to set an observable system.star.cardList(), then call setCardName(). Once all this is done I want saveGame() to execute.

However, setCardName() is not completing before saveGame() is called, so apparently I can't push it into my deferredQueue via a .then().

I'm using jQuery due to working within an ES5 environment.

var setCardName = function (system, card) {
  var deferred = $.Deferred();
  require(["cards/" + card[0].id], function (data) {
    var cardName = loc(data.summarize());
    system.star.ai().cardName = cardName;
    deferred.resolve();
  });
  return deferred.promise();
};

var dealCardSelectableAI = function (win, turnState) {
  var deferred = $.Deferred();

  // Avoid running twice after winning a fight
  if (!win || turnState === "end") {
    var deferredQueue = [];

    _.forEach(model.galaxy.systems(), function (system, starIndex) {
      if (
        model.canSelect(starIndex) &&
        system.star.ai() &&
        system.star.ai().treasurePlanet !== true
      ) {
        deferredQueue.push(
          chooseCards({
            inventory: inventory,
            count: 1,
            star: system.star,
            galaxy: game.galaxy(),
            addSlot: false,
          }).then(function (card) {
            system.star.cardList(card);
            deferredQueue.push(setCardName(system, card));
          })
        );
      }
    });

    $.when(deferredQueue).then(function () {
      deferred.resolve();
    });
  } else {
    deferred.resolve();
  }

  return deferred.promise();
};

dealCardSelectableAI(false).then(function () {
  saveGame(game, true);
});

I tried resolving this by changing the function calls so setCardName() was chained following dealCardSelectableAI(). However, it relies on system.star.cardList() having been written, which in some circumstances had not yet been done.

Given the dependency system.star.cardList() has on chooseCards(), I cannot figure out how to make sure it has been written to before calling setCardName() in a way which blocks saveGame() until everything is done.

8
  • 2
    Do you really need to use jQuery for this? Native Promises are more flexible and (IMO) a lot easier to deal with - I don't see you using jQuery for anything else in the code either Commented Jan 3, 2022 at 20:42
  • apparently using underscore/lodash for a single line of code as well. Yikes. Commented Jan 3, 2022 at 20:49
  • I'm afraid I'm stuck in an ES5 environment., no native promises for me. Commented Jan 3, 2022 at 20:49
  • Which jQuery version are you using? Commented Jan 3, 2022 at 21:10
  • 1
    Simply do return setCardName(system, card); instead of deferredQueue.push(setCardName(system, card)); so that the .then() promise you're pushing to the deferredQueue is fulfillled when the inner setCardName promise fulfills. It seems you're ignoring the result values anyway so it shouldn't matter what value you resolve the promises with. Commented Jan 3, 2022 at 21:13

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.