0

I have following promise functions implemented like

return new Promise(function(resolve, reject) { //logic });
  1. cart.getBasket(req)
  2. cart.updateBasket(req)
  3. cart.updateDefaultShipment(req)
  4. cart.getBasketObject(basket)

Currently I execute code using

   app.post('/Billing', function(req, res) {
        cart.getBasket(req).then(function(basket) {
            cart.updateBasket(req).then(function() {
                cart.updateDefaultShipment(req).then(function(basket) {
                    cart.getBasketObject(basket).then(function(basketObj) {
                        res.render('billing', {
                            basket: basketObj
                        });
                    });
                });
            });
        }).catch(function(error) {
            console.log(error);
        });
    });

I read about Promise.each and thought of using it as the flow of my logic has to be sequential but when I use Promise.each it doesn't work as expected because I saw that inner function of each returns value of every promise execution.

  app.post('/Billing', function(req, res) {

        var asyncCalls = [cart.getBasket(req), cart.updateBasket(req), cart.updateDefaultShipment(req), cart.getBasketObject(basket)];
        Promise.each(asyncCalls, function(basketObj){
            res.render('billing', {
                basket: basketObj
            });
        });
   });

So, is there any cleaner way available to achieve what am doing with .then chain i.e have a cleaner chain.

Also, is it possible in sequential promise execution that the next promise function gets the return value of the previous promise which got executed.

PS : Promise array length will know beforehand.

RanRag
  • 48,359
  • 38
  • 114
  • 167
  • http://bluebirdjs.com/docs/api/promise.reduce.html – Denys Séguret Apr 15 '16 at 14:31
  • Why dont you flatten the chain? There should be no need for the nested promises. `cart.getBasket(req).then(cart.updateBasket.bind(undefined, req).then(cart.updateDefaultShipment.bind(undefined, req))`. You dont have to use bind either, could use an annon function. – ste2425 Apr 15 '16 at 14:40

1 Answers1

3

You can sequence promises without the ever increasing nesting like this:

app.post('/Billing', function(req, res) {
    cart.getBasket(req).then(function(basket) {
        return cart.updateBasket(req);
    }).then(function() {
        return cart.updateDefaultShipment(req);
    }).then(function(basket) {
        return cart.getBasketObject(basket);
    }).then(function(basketObj) {
        res.render('billing', {basket: basketObj});
    }).catch(function(error) {
        console.log(error);
        res.sendStatus(500);
    });
});

Returning a promise from a .then() autoamtically chains it to the parent promise which allows you to use a .then() handler on the parent promise rather than using deeper nesting to continue the sequence.

This automatically passed the results of the prior promise down the chain to the next operation, but it doesn't pass all prior results to subsequent promises. If you need other prior results, you can see various ways to do that here: How to chain and share prior results with Promises

jfriend00
  • 683,504
  • 96
  • 985
  • 979