1

I'm using the Bluebird Promise library in a node script and I'm having trouble understanding the order in which the code is executed. I've got an array of Promises that I'm using the .each method so they get executed in serially in order. In each of those promises I have two chained promises but the second promise is not executed in order that I'm expecting.

If we take the following code, I would have thought the output to be 0.0, 0.1, 0.2, 1.0, 1.1, 1.2 ...etc. But this doesn't seem to the case. It's producing 0.0, 0.1, 1.0, 1.1, 0.2, 1.2 ...etc.

function subPromise1(index)
{
    return new Promise(function (resolve, reject) {
        console.log(String(index) + ".1");
        resolve(index);
    });
}

function subPromise2(index)
{
    return new Promise(function (resolve, reject) {
        console.log(String(index) + ".2");
        resolve(index);
    });
}

var promiseArray = [];
for (var index = 0; index < 2; index++) {
    promiseArray.push(new Promise(function (resolve, reject) {
        console.log(String(index)+".0");
        subPromise1(index).then(subPromise2).then(function (result) {
            resolve(result);
        });
    }));
}

Promise.each(promiseArray, function (index) {
    console.log("Completed " + index);
}).then(function (result) {
    console.log(result);
    process.exit(0);
});

I would have thought the main "each" promise would need to resolve before doing the next promise in the array? Any help in helping understand the issue would be much appreciated.

  • I would suggest looking at that for loop. Promise.each is supposed to be sequential, but that for loop isn't guaranteed to be sequential. – basicallysteve Jan 23 '19 at 11:38
  • `.catch(function (err) { reject(err); });` makes no sense. – Bergi Jan 24 '19 at 22:59
  • Thanks Bergi - it doesn't make sense. I've updated the code. I must of been thinking "try catch" in my head at the time. – Peter Meier Jan 25 '19 at 01:47
  • Also avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it) in that loop! – Bergi Jan 25 '19 at 13:29

2 Answers2

2

The problem is with the for loop and calling the promise inside this loop. The loop doesn't wait for the promise to be fully resolved. If you wish to use async/await then you can get the expected output using the below code.

let result = [];
let indexes = [0, 1];
(async () => {
  for (let index of indexes) {
    console.log(String(index) + ".0");
    const r1 = await subPromise1(index);
    const r2 = await subPromise2(r1);
    result.push(r2);
  }

  console.log(JSON.stringify(result));
})();
shradha
  • 471
  • 3
  • 6
0

In my original thinking I was assuming .each was executing the promises as it was iterating the array which is not the case. It was doing them in the for loop as they were created.

The second parameter of the .each method needs to return the promise for it to executed at that time.

Promise.each(
    [ 0,1 ],
    function (index) {
        return new Promise(function (resolve, reject) {
            subPromise1(index).then(subPromise2).then(function (result) {
                console.log("Completed " + index);
                resolve(result);
            });
        })
    })
    .then(function (result) {
        console.log(result);
        process.exit(0);
    });