0

I have checked through some of the suggested approaches for conditional chaining of promises however I could not find a solution for the use-case I have. Hence posting a fresh question.

Suppose I have:

const promise1 = param1 => {
  return new Promise(resolve => {
    // do something with param1;
    resolve(..);
  });
}

// similarly I have other promises
const promise2 ...

const promise 3 ...

// now I want to call with the following case
const param1 = ...;
promise1(param1)
.then(resp1 => {
  if(resp1 == something) {
    ...
    console.log(resp1) // I want to end here if condition is met
  }
  else {
    ...
    return promise2
  }
})
.then(resp2 => {
   ....
  return promise3
})
.then(resp3 => {
  ....
  console.log(resp3) // else end here
}).
.catch(err => {
  console.log(err)
});

In the above if promise1 returns a specific value I do not want to proceed with promise2 and 3. What is the most elegant way to achieve this? Thanks

RmR
  • 1,917
  • 1
  • 22
  • 35
  • Add the last two continuations to `promise2` directly. Otherwise you'll have to use `async` and `await` to conditionally chain within the `else` block. – Patrick Roberts Mar 15 '19 at 15:13

3 Answers3

0

You have two options. You can append the chains directly to promise2 like this:

const promise1 = param1 => {
  return new Promise(resolve => {
    // do something with param1;
    resolve(...);
  });
};

// similarly I have other promises
const promise2 = ...;

const promise3 = ...;

// now I want to call with the following case
const param1 = ...;
promise1(param1).then(resp1 => {
  if(resp1 == something) {
    ...
    console.log(resp1); // I want to end here if condition is met
  } else {
    ...
    return promise2.then(resp2 => {
      ...
      return promise3;
    }).then(resp3 => {
      ...
      console.log(resp3); // else end here
    });
  }
}).catch(err => {
  console.log(err);
});

Or you can use async and await within the first continuation:

const promise1 = param1 => {
  return new Promise(resolve => {
    // do something with param1;
    resolve(...);
  });
};

// similarly I have other promises
const promise2 = ...;

const promise3 = ...;

// now I want to call with the following case
const param1 = ...;
promise1(param1).then(async resp1 => {
  if(resp1 == something) {
    ...
    console.log(resp1); // I want to end here if condition is met
  } else {
    ...
    const resp2 = await promise2;
    ...
    const resp3 = await promise3;
    ...
    console.log(resp3); // else end here
  }
}).catch(err => {
  console.log(err)
});
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
0

Promise chains are not elegant for this. You have to specify the whole flow upfront:

promise1(param1)
.then(resp1 => {
  if(resp1 == something) {
    ...
    console.log(resp1) // I want to end here if condition is met
  }
  else {
    ...
    return promise2.then(resp2 => {
      ....
      return promise3
    })
    .then(resp3 => {
      ....
      console.log(resp3) // else end here
     })
  }
})
.catch(err => {
  console.log(err)
});

If you can use async/await, it will be much more elegant

async function doSomething(){
    const resp1 = await promise1(param1);
    if(resp1 == something) {
      return resp1;
    }

    const resp2 = await createPromise2(resp1);
    const resp3 = await createPromise3(resp2);
    return resp3;
}
libik
  • 22,239
  • 9
  • 44
  • 87
  • Agree @libik that async/await seems correct (and I will mark this as the answer) except I forgot to mention that this function is expected to be a promise by the caller (its a google actions project) – RmR Mar 16 '19 at 03:36
0

Using async/await would be the best solution here, because what you need is in fact synchronization:

(async () => {
    const promise1 ...
    const promise2 ...
    const promise3 ...

    const resp1 = await promise1(param1);
    if (resp1 == something) {
       console.log(resp1) // I want to end here if condition is met
    } else {
        const resp2 = await promise2;
        const resp3 = await promise3;

        console.log(resp3) // else end here
    }
})();

EDIT: snippet into an async function.

ttulka
  • 10,309
  • 7
  • 41
  • 52