1

I am struggling with many aspects when dealing with Promises after promises, API calls inside For..Loops and my guess is that I'm developing promises anti-patterns.

This exact codepen illustrates my issue with Promises:

http://codepen.io/ghuroo/pen/EZWoGQ?editors=0010

Code sample:

$('#start').on('click', function() {
    log('here we go: ');

    promise1().then(function(success) {
        log(success);

        promise2().then(function(success) {
            log(success);

            promise3().then(function(success) {
                log(success);

            }).catch(function(error) { log(error); });
        }).catch(function(error) { log(error); });
    }).catch(function(error) { log(error); });

});

Any help on how to improve my code? As you can see, I can't get the for..loop to log in the right order, it seems like it never resolves..

Also, any tips on how to prevent the waterfall thing? (I would like to print the error only once, instead of one for each promise call)

Edit:

For anyone looking for the solution, here's @jaromanda-x's solution: http://codepen.io/ghuroo/pen/pReLZm?editors=0010

ghuroo
  • 318
  • 2
  • 10
  • 1
    There are more duplicates, with different approaches, for example http://stackoverflow.com/questions/29546898/run-bluebird-promises-sequentially-without-return-values. Functions to [read about](http://bluebirdjs.com/docs/api-reference.html): `Promise#each`, `Promise#map`, `Promise#mapSeries`, `Promise#reduce`, they all can deal with these situations, each specializes in a certain aspect. – Tomalak Jan 20 '17 at 13:22

2 Answers2

2

For your promise3

function promise3() {
    // NOTE: this function returns a function
    function delay(value) {
        return function() {
            return new Promise(function(resolve) {
                setTimeout(resolve, 500, value);
            });
        }
    }    
    log('promise 3 started (takes 4*500ms = 2 seconds)');
    var p = Promise.resolve();

    for (i = 0; i < 4; i++) {
        p = p.then(delay(i)).then(function(n) {
            log('promise 3 - iteration nr. ' + n);
        })
    }
    return p.then(function() {
        return '<b>i\'m done 3</b>';
    });
};
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • can't thank you enough :) fixed version here: http://codepen.io/ghuroo/pen/pReLZm?editors=0010 – ghuroo Jan 20 '17 at 13:19
  • 1
    @ghuroo Here is a version that uses more of the features that Bluebird offers you. Compare: http://codepen.io/anon/pen/XpMYMY – Tomalak Jan 20 '17 at 14:51
  • @Tomalak thank you, just what I was looking for: improve my logic and usage of bluebird (no need for async then). kudos to you :) – ghuroo Jan 20 '17 at 16:16
1

I usually write them more like this:

promise1()
   .then(function (success) {
       log(success);
       return promise2();
   })
   .then(function (success) {
       log(success);
       return promise3();
   })
   .then(function (success) {
       log(success);
   })
   .catch(function (error) {
       log(error);
});
jjwilly16
  • 410
  • 2
  • 8
  • 15