skip to Main Content

I have tried to implement promise chaining in Javascript with 3 simple promises. First promise I am resolving and last 2 I am rejecting. Till 2nd rejection it is working fine. But after the catch statement it is throwing error again for 3rd promise. I want to use only one catch block.

var promise1 = new Promise((resolve, reject) => resolve("1st resolved"));
var promise2 = new Promise((resolve, reject) => reject("2nd rejected"));
var promise3 = new Promise((resolve, reject) => reject("3rd rejected"));

// promise chaining
promise1
  .then((res) => {
    console.log(res);
    return promise2;
  })
  .then((res) => {
    console.log(res);
    return promise3;
  })
  .then((res) => {
    console.log(res);
  })
  .catch((err) => console.log("error in promise", err));

I have attached the error also
Please refer this for error – (https://i.sstatic.net/pQ9wE5fg.png)

2

Answers


  1. Many things in your code are syntactic wrong.

    1- you are declaring a variable:
    var promise1 = new Promise((reso..
    instead of declaring a function:
    const promise1 =()=> new Promise((reso..
    or
    function promise1(){ return new Promise((re....}

    2- in your code promise1 is a variable and not function,
    so when you use a function, the syntax is
    [function mame] + ( + […arguments] + ).
    note the open and close parenthesis.

    3- the then syntax is particular, it accept 2 functions : first one for the resolve, second one for the reject.

    Correct way for coding this:

    const 
      promise1 =_=> new Promise((resolve, reject) => resolve("1st resolved"))
    , promise2 =_=> new Promise((resolve, reject) => reject("2nd rejected"))
    , promise3 =_=> new Promise((resolve, reject) => reject("3rd rejected"))
      ;
    
    // promise chaining
    promise1()
    .then
      ( res => { console.log('res1', res) ; return promise2(); }
      , rej => { console.log('rej1', rej) ; return promise2(); }
      )
    .then
      ( res => { console.log('res2', res) ; return promise3(); }
      , rej => { console.log('rej2', rej) ; return promise3(); }
      )
    .then
      ( res => { console.log('res3', res); }
      , rej => { console.log('rej3', rej); }
      )
    .catch((err) => console.log("error in promise", err));
    Login or Signup to reply.
  2. But after the catch statement it is throwing error again for 3rd promise.

    This happens because the second then-callback does not execute (as that would only happen when promise2 fulfills), and by consequence, promise3 is not made part of the promise chain and thus its rejection remains uncaught.

    It is not a common pattern to first create a promise (like promise3) and only later use such a promise as a return value inside a then-callback. Usually you would only create the promise when the relevant then-callback is executed. If you would have done it that way, there would not have been this problem, as you can see here:

    var promise1 = new Promise((resolve, reject) => resolve("1st resolved"));
    
    // promise chaining
    promise1
      .then((res) => {
        console.log("promise1 resolved:", res);
        var promise2 = new Promise((resolve, reject) => reject("2nd rejected")); // <---
        return promise2;
      })
      .then((res) => {
        console.log("promise2 resolved:", res);
        var promise3 = new Promise((resolve, reject) => reject("3rd rejected")); // <---
        return promise3;
      })
      .then((res) => {
        console.log("promise3 resolved:", res);
        console.log(res);
      })
      .catch((err) => console.log("error in promise:", err));

    If on the other hand, you really want to create all three promises, no matter what happens to them, and your goal is to get into the final then-callback when they all have resolved, or into a common handler when at least one of them is rejected, then use Promise.all:

    var promise1 = new Promise((resolve, reject) => resolve("1st resolved"));
    var promise2 = new Promise((resolve, reject) => reject("2nd rejected"));
    var promise3 = new Promise((resolve, reject) => reject("3rd rejected"));
    
    Promise.all([
        promise1.then((res) => {
            console.log("promise1 resolved:", res);
            return res;
        }), 
        promise2.then((res) => {
            console.log("promise2 resolved:", res);
            return res;
        }),
        promise3.then((res) => {
            console.log("promise3 resolved:", res);
            return res;
        }),
    ]).then(
        (res) => console.log("success. results are:", res),
        (err) => console.log("error in a promise:", err)
    );

    In this implementation, there are the following points to highlight:

    • The promises are no longer chained (note how the return statements in the callbacks changed). This chaining is not necessary, because they were already created, and the ultimate goal of your chaining was only to know when all three had resolved (or any had rejected). You don’t need chaining for that, but Promise.all.

    • Promise.all will detect when one of the promises rejected (in this case it detects the rejection of promise2 first), and will absorb the rejection of any of the other promises that might also reject — in this case the rejection of promise3.

    • The promise that Promise.all returns will either fulfill or reject, and so I have provided a handler for both cases by providing two callbacks to that final then.

    Difference

    The above two snippets output the same result. The difference is that in the first case promise3 is not created (considering it only makes sense to do so when promise2 fulfills), while in the second case it is.

    Choose the pattern you need for your case.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search