vinoli
vinoli

Reputation: 457

Sequential promises

I need to get four response's promises, but to do this I first have to call every function in sequence, from the first to the last. You can see from my code that I call the next function in the promise callback from the last called function.

But the code doesn't look appropriate, so I need to know if there is some better way to do this.

Any suggestions?

$scope.createPayment = function() {
    var dados = $scope.card;
// get first promise
    PagamentoMP.createToken(dados)
    .then(
        function(result) {
            dados.token = result;
// get second promise
            PagamentoMP.guessPaymentMethod(dados)
            .then(
                function(result) {
                    dados.paymentMethod = result;
// get third promise            
                    PagamentoMP.getIssuers(dados)
                    .then(
                        function(result) {
                            dados.issuer = result;
// get fourth promise 
                            PagamentoMP.getInstallments(dados)
                            .then(
                                function(result) {
                                    dados.installments = result;     
                                },  
// error for fourth promise
                                function(result) {
                                    console.log("getInstallments PAGAMENTOMP -> Failed to get the name, result is " + result); 
                                }
                            );
                        },
// error for third promise                      
                        function(result) {
                            console.log("getIssuers PAGAMENTOMP -> Failed to get the name, result is " + result); 
                        });
                    },
// error for second promise                 
                    function(result) {
                        console.log("guessPaymentMethod PAGAMENTOMP -> Failed to get the name, result is " + result); 
                    });
                },
// error for first promise              
            function(result) {
                console.log("createToken PAGAMENTOMP -> Failed to get the name, result is " + result); 
            });
    };

Upvotes: 0

Views: 79

Answers (1)

afuous
afuous

Reputation: 1498

Instead of doing this,

a().then(function(result) {
    b(result).then(function(result) {
        c(result).then(function(result) {
            console.log("done");
        });
    });
});

you can chain all the promises at the top level.

a()
    .then(function(result) {
        return b(result);
    })
    .then(function(result) {
        return c(result);
    })
    .then(function(result) {
        console.log("done");
    });

This same pattern can be used in your code.

To catch errors, add a .catch at the end of the chain if you want one error handler for all errors in the chain.

a()
    .then(function(result) {
        console.log("done");
    })
    .catch(function(err) {
        console.error(err);
    });

For separate error handlers at each step, you can do something like this:

a()
    .catch(function(err) {
        console.log("error in a");
        throw err;
    })
    .then(function(result) {
        return b()
            .catch(function(err) {
                console.log("error at b");
                throw err;
            });
    })
    .then(function(result) {
        return c()
            .catch(function(err) {
                console.log("error at c");
                throw;
            });
    });

Each error handler needs to call throw so that it does not continue down the chain when an error happens.

Upvotes: 1

Related Questions