2

I have a chain of jQuery promises, but I would like to skip one of them depending on the response of an earlier promise.

My code is something like:

getMoney()
  .then(getBeer)
  .then(getFireworks)
  .then(getLighterfluid)
  .then(getCrazy);

If the promise in my getFireworks function returns something like 'No fireworks available', then I want to skip the getLighterFluid promise, and move on to getCrazy.

How could I approach this with my current setup? Or do I need to rework this?

Amit
  • 45,440
  • 9
  • 78
  • 110
Ben
  • 5,283
  • 9
  • 35
  • 44

2 Answers2

2

There are many ways around this, but essentially you have to change something in the structure of the chain, or the functions themselves.

In this case, I'd wrap the getLighterfluid with a helper like this:

getMoney()
  .then(getBeer)
  .then(getFireworks)
  .then(function(val) { if(val != 'No fireworks available') return getLighterfluid(val); })
  .then(getCrazy);

You could generalize this pattern if you need to use it a lot:

function conditionally(predicate, handler) {
  return function(val) {
    if(predicate(val) {
      return handler(val);
    }
  };
}

function notEqualFunc(val) {
  return function(v) {
    return v != val;
  };
}

getMoney()
  .then(getBeer)
  .then(getFireworks)
  .then(conditionally(notEqualFunc('No fireworks available'), getLighterfluid))
  .then(getCrazy);

You could create whatever predicate prototype you need instead of notEqualFunc and make the code quite descriptive.

Amit
  • 45,440
  • 9
  • 78
  • 110
2

Assuming that getFireworks resolves to [ { type: "rocket" } ] or similar then getLighterFluid could just do nothing.

function getLighterFluid(fireworks) {
    if (!fireworks.length) return;

    //go get that lighter fluid
}
Steve Greatrex
  • 15,789
  • 5
  • 59
  • 73
  • A similar but more comprehensive approach would be to use any of the solutions offered to the question [How do I access previous promise results in a .then() chain](http://stackoverflow.com/questions/28250680/how-do-i-access-previous-promise-results-in-a-then-chain). That would allow you to take into account all/any of the previous async results anywhere further down the chain. For example, you could keep track of how much money remains at each stage and spend accordingly, or determine the magnitude of "getCrazy" depending on how much beer and fireworks were bought. – Roamer-1888 Nov 06 '15 at 18:20