bummzack
bummzack

Reputation: 5875

How do I chain multiple conditional promises?

In my code I have conditional tasks, which all return a promise. I need the tasks to run in sequence.

My current implementation looks something like this:

var chain = [];

if (/* some condition for task A */) {
    chain.push(function(doContinue){
        taskA().then(doContinue);
    });
}

if (/* some condition for task B */) {
    chain.push(function(doContinue){
        taskB().then(doContinue);
    });
}

if (/* some condition for task C */) {
    chain.push(function(doContinue){
        taskC().then(doContinue);
    });
}

var processChain = function () {
    if (chain.length) {
        chain.shift()(processChain);
    } else {
        console.log("all tasks done");
    }
};

processChain();

This works fine, but initially I was looking for a way to create the chain using only Promises and chaining all functions using .then, but I wasn't able to get a working solution.

If there's a cleaner way using only Promises and chains of then calls, then I'd love to see an example.

Upvotes: 25

Views: 17485

Answers (2)

raina77ow
raina77ow

Reputation: 106375

One possible approach:

var promiseChain = Promise.resolve();
if (shouldAddA) promiseChain = promiseChain.then(taskA);
if (shouldAddB) promiseChain = promiseChain.then(taskB);
if (shouldAddC) promiseChain = promiseChain.then(taskC);
return promiseChain;

Another one:

return Promise.resolve()
  .then(shouldAddA && taskA)
  .then(shouldAddB && taskB)
  .then(shouldAddC && taskC);

Upvotes: 32

Mulan
Mulan

Reputation: 135197

You can use the new async/await syntax

async function foo () {
  let a = await taskA()
  if (a > 5) return a // some condition, value

  let b = await taskB()
  if (b === 0) return [a,b] // some condition, value

  let c = await taskC()
  if (c < 0) return "c is negative" // some condition, value

  return "otherwise this"
}

foo().then(result => console.log(result))

What's nice about this is – aside from the code being very flat and readable (imo) – values a, b, and c are all available in the same scope. This means your conditions and return values can depend on any combination of your tasks' promised values.

Upvotes: 5

Related Questions