Sequential execution of Promise [duplicate]

2019-09-10 07:06发布

问题:

This question already has an answer here:

  • Aren't promises just callbacks? 8 answers

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.

回答1:

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