caefer
caefer

Reputation: 63

javascript ES6 / how to correctly chain Promises and implement handling

I have written a class to capture a microservice accessed vi https. Several calls have been implemented in asynchronous methods which all work fine by themselves (here: step1(), step2(), step3()).

However I want to call a few of those in succession (run()) to implement certain workflows.

What I can not manage so far is that the stepX methods get called after another. Also I want to call run() and get a promise back so I can .then() when all is done. Also I want to implement some error handling there to catch all errors that might occur during the chain.

Here's a class that reduces my problems to the core:

class Foo {
  run() {
    return this.step1()
    .then(() => this.step2())
    .then(() => this.step3())
  }

  step1() {
    console.log('1')
    return new Promise(function(resolve) { 
       setTimeout(function(){console.log('2')}, 500)
    });
  }

  step2() {
    console.log('3')
    return new Promise(function(resolve) { 
       setTimeout(function(){console.log('4')}, 500)
    });
  }

  step3() {
    console.log('5')
    return new Promise(function(resolve) { 
       setTimeout(function(){console.log('6')}, 500)
    });
  }
}

let bar = new Foo();

bar.run()
.then(console.log('7')) // react on run() finishing successfully
.catch(err => console.log('err:', err)) // global error handling

I expected this to output the numbers 1 to 7 in correct order. However the current output is

1
7
2

Thank you for any help! Christian

Upvotes: 0

Views: 73

Answers (2)

Srinath Kamath
Srinath Kamath

Reputation: 558

You can use async-await approach with try-catch-finally to handle the resolve & reject cases in promises. I'm writing tweaking the code a little bit to write the example by using a static function. you can use it as you normally would.

class Foo {
  static async run() {
    let response = {status:false, result:'Failed' }
    try{
        const step1_response = await step1();
        const step2_response = await step2();
        response.status = true;
        response.result = {step1_response, step2_response};
    } catch(error) {
        console.log(error)
    } finally {
       return response;
    }
  }
}

Upvotes: 0

jfriend00
jfriend00

Reputation: 707158

There were a couple problems in your code:

  1. You weren't resolving the promises in step1(), step2() and step3().
  2. .then(console.log('7')) was calling the console.log() immediately and not waiting for the promise. You must pass a callback to .then().

With these two issues fixed, here's the resulting code which you can run in the snippet and see the desired output:

class Foo {
    run() {
        return this.step1()
            .then(() => this.step2())
            .then(() => this.step3())
    }

    step1() {
        console.log('1')
        return new Promise(function(resolve) {
            setTimeout(function() { 
                console.log('2');
                resolve(); 
            }, 500)
        });
    }

    step2() {
        console.log('3')
        return new Promise(function(resolve) {
            setTimeout(function() { 
                console.log('4');
                resolve(); 
            }, 500)
        });
    }

    step3() {
        console.log('5')
        return new Promise(function(resolve) {
            setTimeout(function() { 
                console.log('6');
                resolve(); 
            }, 500)
        });
    }
}

let bar = new Foo();

bar.run()
    .then(() => console.log('7')) // react on run() finishing successfully
    .catch(err => console.log('err:', err)) // global error handling

This generates the output:

1
2
3
4
5
6
7

Upvotes: 2

Related Questions