Successive vows

I'm trying to retrieve responses from four promises, but I currently have to call each function in sequence one after the other. In my code, you can see that I trigger the next function within the promise callback of the previously called function.

However, the current implementation doesn't seem optimal to me, so I'm wondering if there's a better way to achieve this.

Any suggestions on how to improve this?

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

Answer №1

Instead of executing the following code,

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

You can streamline the promise chaining by keeping all 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 approach can also be applied in your own code.

To handle errors, you can append a .catch at the end of the chain for a single error handler for all errors within the chain.

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

If you prefer separate error handlers at each step, you can implement the following:

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 must include throw to prevent further execution down the chain upon encountering an error.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating background color animations with Jquery hover

<div class="post_each"> <h1 class="post_title">Single Room Apartments</h1> <img class="thumb" src="1.jpg"/> <img class="thumb" src="1.jpg"/> <img class="thumb" src="1.jpg"/> <img class="thumb last" ...

When access to Ajax .responseText in an alert it can be displayed, however it cannot be stored in a variable or

var response_var=""; // Added for debugging purposes ajax.onreadystatechange = function() { if (ajax.readyState == 4 & ajax.status == 200) { response_var = ajax.responseText; alert(ajax.responseText); // This alerts properly (some text ...

How can I retrieve the position of a div or an image within a div (specifically the top and left coordinates) and incorporate these values into CSS?

I'm currently working on a website that is dynamic and utilizes bootstrap. I am looking to incorporate an animation where the dynamic thumbnails in the col-md-4 div zoom to 100% when clicked, appearing at the center of the container. I am struggling ...

Unable to navigate using react-router after logging out without a page refresh

In my logout approach, everything seems to work fine - there are no errors in the console, localHistory is cleared successfully, but for some reason it cannot navigate to the login page without refreshing the current page. const handleLogout = () => { ...

Is your pure function component not receiving or responding to input props correctly?

Here is my code snippet: const actionCreators = { action: AppReducer.actionCreators.action } interface GlobalState { user: Model.User | null; } interface InputState { setStashBarWidth(width: number); stashWidth: number; } const Header = ...

When executed, the Node application successfully compiles

I have a TypeScript application that runs smoothly in development mode using ts-node. However, after building the application, I encounter some unexpected warnings and errors. This is my tsconfig.json: { "compilerOptions": { "incremen ...

Executing asynchronous JavaScript calls within a loop

I've encountered an issue with asynchronous calls in JavaScript where the function is receiving unexpected values. Take a look at the following pseudo code: i=0; while(i<10){ var obj= {something, i}; getcontent(obj); / ...

Unable to load the node modules

In my development journey, I created an ASP.NET MVC project using Angular 2 in Visual Studio 2017 and set up node for package management. Here is a snippet from the package.json file: { "version": "1.0.0", "name": "asp.net", "private": true, ... ...

"Create a new row in the list by selecting an option from the drop-down

I'm experimenting with the following scenario. There is a function that reveals a hidden list based on a dropdown selection. To see it in action, please click here. What I am aiming to achieve is for Option1 to display the content of #List-Option1 ...

Extracting data from website's table using JavaScript and opening the link in href

My goal is to extract the details page for each link found on this particular page. The link provides access to all the information required: PAGE However, I'm interested in extracting details from pages that have links like this: href="javascr ...

What is the best way to make JavaScript display the strings in an array as bullet points on different lines?

We were assigned a task in our computer science class to analyze and extend a piece of code provided to us. Here is the given code snippet: <!DOCTYPE html> <html> <head> <title>Example Website</title> </head> <body& ...

Specialized express Validator for 2 particular fields

I currently have 2 custom validators set up for the fields email and phone. check('phone') .not() .isEmpty() .withMessage('Phone should not be empty') .custom(async phone => { const phoneCheck = await ...

What is the process for obtaining intersection set data from an array?

I'm trying to find the intersection set within an array only containing type 1 and 2. Can you help me with that? var arr = [ { id: 1, auths: [ { authId: 1, type: 1, value: 'Test1' }, { authId: 2, type: 1, ...

Tips for utilizing JavaScript functions within Vue directives?

Let's say I have a JS function that looks like this: function myFunc() { return true; } Now, I want to display an element if the output of the function is true: <p v-if="myFun()">I am Test</p> I understand that I can place the myFun ...

View the picture directly on this page

Currently, I am in the process of creating a gallery and I would like the images to open on top of everything in their original size when clicked by the user. My expertise lies in HTML and CSS at the moment, but I am open to learning JavaScript and jQuery ...

Setting up Karma configuration to specifically exclude nested directories

When unit testing my Angular 2 application using Karma, I encountered an issue with my directory structure: └── src/ ├── index.js ├── index.js.text ├── index.test.js ├── README.txt ├── startuptest.js ...

Something is not quite right when the page is loading in a Ruby on Rails application

In the process of developing a wiki clone, I am faced with an issue involving JavaScript. When I navigate to a specific page by clicking on a link, the JavaScript does not function properly until I refresh the page. The JavaScript aspect mainly involves an ...

run a function once ngFor has completed rendering the data

I'm attempting to run a function every time my ngFor finishes loading data from the API. However, the callback only works on the initial load of the ngFor. How can I make sure that the callback is executed whenever my ngFor data changes? I found a ...

Is it possible for Angular Parent & Child Scope to function properly within the $root scope?

I came across two examples showcasing parent and child scope inheritance. The first example utilizes parent and child controllers, while the second example relies on root scope. Interestingly, the second example does not produce the expected results. What ...

What is the best way to store the result from a JavaScript FileReader into a variable for future reference?

I am currently facing an issue uploading a local .json file to my web application. I have managed to display the file in the dev tools, but I am unable to make it accessible for further use. It seems like the problem lies in how I handle (or fail to handle ...