9

I am trying to execute a series of promises in order, only going to the next one after the previous is resolved. From Bluebird docs:

The iterator won't be called for an item until its previous item, and the promise returned by the iterator for that item are fulfilled. http://bluebirdjs.com/docs/api/promise.mapseries.html

var Promise = require('bluebird');


function test(time) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            console.log(time);
            resolve(time);
        }, time);
    });
}

Promise.mapSeries([test(2000), test(1000), test(500), test(3000)], function(a) {
    return a;
}).then(function(results) {
    console.log(results);
});

What I expect is that the console.log inside the test function to show: 2000, 1000, 500, 3000 in that order. I expect that because as the docs states, each item goes only after the previous is resolved. Instead, I get 500, 1000, 2000, 3000, which reflects that all the functions are called instanstaneously. Moreover, results does show the results in the order they were called, though that is irrelevant at this point.

Am I misunderstanding something here?

yBrodsky
  • 4,981
  • 3
  • 20
  • 31
  • _Creating_ a promise (which is what `test` does) is a synchronous operation. – robertklep Mar 03 '17 at 15:36
  • Sure, still I expect Bluebird to do some magic and wait to call on the next test until the previous is done. Ain't that what the doc says? – yBrodsky Mar 03 '17 at 15:39
  • 2
    There's a difference between an iterator returning promises for an item, and items that are themselves promises (which is what happens in your case). Once you call `test`, the promise that it returns "starts" (so `setTimeout` is called). The answer given shows how to postpone the creation of the promise until Bluebird explicitly asks for it (which is the only way it can work). – robertklep Mar 03 '17 at 15:49

1 Answers1

15

Your test calls are being before Promise.mapSeries ever gets a chance to run. Also mapSeries is normally run on a promise instance. Maybe the following example helps to understand? Note how test(time) this time returns a function.

function test(time) {
    return function(value) {
      return new Promise(function(resolve, reject) {
          setTimeout(function() {
              console.log('time', time);
              resolve(time);
          }, time);
      });
    };
}

Promise.resolve([test(2000), test(400), test(1000), test(1), test(5000)])
       .mapSeries(function(asyncMethodPassed) {
                    return asyncMethodPassed();
}).then(function(results) {
    console.log('result', results);
});
Shashank Vivek
  • 16,888
  • 8
  • 62
  • 104
Ben Dadsetan
  • 1,565
  • 11
  • 19